Bean Injection After DataTable

425 Views Asked by At

I have a page with a datatable that reads data from a service class. That service class is suppose to be injected with a contactDAO but it does not get injected right away. In fact, when the page first loads up, the data table is empty because the DAO has not been injected yet. However, if I call addContact(), the list 'contacts' is updated fine because the contactDAO is injected by then.

How do I ensure the contactDAO is injected before the datatable needs to use the service class? I am using Spring 3 and JSF 2.0.

The page with the datatable is bind to the list 'contactServiceImpl.contacts':

<h:dataTable var="contact" value="#{contactServiceImpl.contacts}">
...
</h:dataTable>

My ContactServiceImpl looks like this:

@Service
public class ContactServiceImpl implements ContactService {

    private static List<Contact> contacts = new ArrayList<Contact>();

    @Autowired
    private static ContactDAO contactDAO;

    private ContactServiceImpl() {
        contacts = new ArrayList<Contact>();

        //TODO: need to inject contactDAO at the same time as instantiation
        contacts.clear();
        try {
            contacts.addAll( contactDAO.getContacts() );
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void addContact(Contact contact) {
        contacts.add(contact);
        contactDAO.addContact(contact);

        contacts.clear();
        contacts.addAll( contactDAO.getContacts() );
    }

    @Autowired
    public void setContactDAO(ContactDAO contactDAO) {
        ContactServiceImpl.contactDAO = contactDAO;
        System.out.println("DAO is injected");
    }
}

And applicationContext.xml

  <bean id="contactServiceImpl" class="com.example.service.ContactServiceImpl"
        scope="session">
        <property name="contactDAO" ref="contactDAOImpl"/>
  </bean>
1

There are 1 best solutions below

1
On BEST ANSWER

Spring always create bean before inject propertes with constructor, so you can't use injected properties before they injected. To solve this problem you must rewrite logic or get contactDAO as constructor arg (I'm know VERY ugly solution, but work)

    private ContactServiceImpl(ContactDAO costrContactDAO) {
    contacts = new ArrayList<Contact>();

    //TODO: need to inject contactDAO at the same time as instantiation
    contacts.clear();
    try {
        contacts.addAll( costrContactDAO.getContacts() );
    } catch (Exception e) {
        e.printStackTrace();
    }
  }


  <bean id="contactServiceImpl" class="com.example.service.ContactServiceImpl"
    scope="session">
    <constructor-arg ref="contactDAOImpl"/>
    <property name="contactDAO" ref="contactDAOImpl"/>
  </bean>

Higly recommend search other solution (For example, I'm use Wicket in my projects, there is another concept of rendering tables - using DataProviders so i'm don't have such problem, may be you can use this concept in your JSF project)