6

The spec says that CDI container removes a SFSB when the scope's context is about to be destroyed. How does it exactly remove the EJB? It does not seem to be calling the method annotated with @Remove.

@Stateful
public class CustomerDAOImpl implements CustomerDAO {
    @PreDestroy
    public void onDestroy() {
        //This is getting called as expected
    }
    @Remove
    public void deleteMyBean() {
        //This is not getting called!
    }
}

So, CDI is technically doing what the spec says. The question is how is it managing to ask the EJB container to remove the instance? Thanks.

RajV
  • 6,860
  • 8
  • 44
  • 62

3 Answers3

3

I think the CDI container needs a hook into the EJB container to ask it to "do what you'd do if an @Remove method had just completed". Looking at EJB spec, EJB 2.1 had a mechanism for this in the interfaces you had to extend.

For obvious reasons, the container calling an arbitrary @Remove annotated method for the side effect is pretty ill advised.

covener
  • 17,402
  • 2
  • 31
  • 45
  • +1, but as a nit, the container owns the implementation of EJBObject (which has .remove, which is basically what CDI wants to use), but the bean implements SessionBean. – Brett Kail May 05 '12 at 21:39
  • This is not an answer but a speculation. If indeed there was such a hook,it will be highly vendor specific. How can an implementation like Weld do it in a generic fashion. – RajV May 11 '12 at 02:22
  • The question isn't if how weld does it portably. Weld specifically requires container to provide all sorts of implementations of interfaces, including SessionObjectReference#remove – covener May 27 '12 at 22:02
2

As covener says this is done using an implementation specific EJB API, that isn't part of the EJB standard API.

As covener says, calling @Remove is NOT the right way to proceed. @Remove methods are called by users code, and tell the EJB container to remove the EJB. If you want a callback when the EJB is removed, use @PreDestroy.

Pete Muir
  • 232
  • 1
  • 3
-1

The method with @Remove annotation must be called explicitly by the client, then the container will call the method annotated with @PreDestroy implicitly, if it exists. After that, the bean instance will be ready for garbage collection.

This is the only lifecycle method which client can control, all other methods are controlled by the container.

Nayan Wadekar
  • 11,444
  • 4
  • 50
  • 73
  • Yes, that is the normal behavior. But how is the CDI container removing the EJB? Is it using some kind of undocumented API to ask the EJB container to do the removal? – RajV May 02 '12 at 20:42
  • @RajV I was not able to locate it in specification, but you can find useful information in Java EE tutorial, in `The Life Cycle of a Stateful Session Bean` sestion at http://docs.oracle.com/javaee/5/tutorial/doc/bnbmt.html – Nayan Wadekar May 02 '12 at 21:14