manban
manban

Reputation: 133

EJB @PostConstruct not called

When I want to invoke a method with @PostConstruct, the method is not invoked. I don't get any errors or logs from the server. Do I have to add some configuration xml files or add additional annotations to invoke the method?

Serlvet:

public class PersonServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;
    private static final Logger LOG = LoggerFactory.getLogger(PersonServlet.class);

    @EJB
    Storage storage;

    protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
      try {
        HttpSession session = req.getSession(true);
        storage = (Storage) session.getAttribute(Storage.class.getName());
        if (storage == null) {
           storage = new Storage();
           session.setAttribute(Storage.class.getName(), storage);
        }     
        // create odata handler and configure it with CsdlEdmProvider and Processor
        OData odata = OData.newInstance();
        ServiceMetadata edm = odata.createServiceMetadata(new PersonEdmProvider(), new ArrayList<EdmxReference>());
        ODataHttpHandler handler = odata.createHandler(edm);
        handler.register(new PersonEntityCollectionProcessor(storage));
        handler.register(new PersonEntityProcessor(storage));
        handler.register(new PersonPrimitiveProcessor(storage));

        // let the handler do the work
        handler.process(req, resp);
      } catch (RuntimeException e) {
        LOG.error("Server Error occurred in ExampleServlet", e);
        throw new ServletException(e);
      }
    }
}

PersonDAO

@Stateless
public class PersonDAO {

    @PersistenceContext
    private EntityManager em;

    public List<Person> getAllPersons() {

        return 
            em.createQuery("SELECT p FROM T_Person p", Person.class).getResultList();

    }

}

Storage:

@Stateless
public class Storage {

    @EJB
    PersonDAO psDAO;

    private List<Entity> personList;

    public Storage() {
        personList = new ArrayList<Entity>();
    }

    @PostConstruct
     private void initSampleData(){
         psDAO.getAllPersons();
    }
}

PersonEntityCollectionProcessor:

public class PersonEntityCollectionProcessor implements EntityCollectionProcessor {

    private OData odata;
    private ServiceMetadata serviceMetadata;
    private Storage storage;

    public PersonEntityCollectionProcessor(Storage storage) {
        this.storage = storage;
    }

    public void init(OData odata, ServiceMetadata serviceMetadata) {
        this.odata = odata;
        this.serviceMetadata = serviceMetadata;
    }

}

Upvotes: 1

Views: 2201

Answers (2)

unwichtich
unwichtich

Reputation: 13857

I think the problem is this part of your code:

    storage = (Storage) session.getAttribute(Storage.class.getName());
    if (storage == null) {
       storage = new Storage();
       session.setAttribute(Storage.class.getName(), storage);
    }    

With this you create a non-managed instance of the Storage instead of using the injected instance and therefore the @PostConstruct is not called. If the instance of Storage injected via @EJB is null when this code is executed, you may have a problem with the injection.

You can remove these 5 lines and it should work. You don't need to save instance manually in the session.

Upvotes: 4

k5_
k5_

Reputation: 5558

Most EJBs are lazily initialized, so @PostConstruct is only/first called when you actually use an instance of that bean.

That said; you never use the actual sessionbean in storage from the servlet, so no need to ever call @PostConstruct

You overwrite it from the session, or recreate it

    storage = (Storage) session.getAttribute(Storage.class.getName());
    if (storage == null) {
       storage = new Storage();
       session.setAttribute(Storage.class.getName(), storage);
    }     

Upvotes: 3

Related Questions