What is the EJB 3.0 version of method ejbCreate
Asked Answered
P

3

5

I would like to migrate some old EJB 2.1 code to EJB 3.0, but there is some handling of configuration errors in the ejbCreate method. Is there an EJB 3 version of that method?

Edit: In EJB 2.x ejbCreate could throw a CreateException. Based on the documentation of @PostConstruct etc. I can no longer throw any checked Exceptions. How can i handle this if i cannot migrate the code using the EJB right now.

Edit2: The frontend specifically handles CreateException which unfortunately is checked.

Procter answered 27/10, 2011 at 19:4 Comment(0)
P
8
@PostConstruct
public void anyName() {
    //initialization code, dependencies are already injected
}

No only the name is arbitrary, you can have several @PostConstruct methods in one EJB - however the order of invocation is unspecified, so be careful and try to stick with one method. UPDATE:

Only one method can be annotated with this annotation.

Postexilian answered 27/10, 2011 at 19:6 Comment(6)
In EJB 2.x ejbCreate could throw a CreateException. Based on the documentation of @PostConstruct i can no longer throw any checked Exceptions. How can i handle this if i cannot migrate the code using the EJB right now.Procter
"f the method throws an unchecked exception the class MUST NOT be put into service" - from docs. Why do you want to use checked exceptions on the first place? Also you cannot have several @PostConstruct methods, works in Spring, but not in EJB, sorry.Postexilian
I dont want to use checked exceptions. But the code using the EJB handles CreateException based on the 2.x spec which is checked. And i currently cant modify that code.Procter
What was the purpose of ejbCreate(-) in EJB 2.x? The @PostConstruct method will be invoked by the container when new instance of the EJB is created and DI has occured. Maybe you need a @PostConstruct method to do your configuration, and some mockup (regular method) which simulates the ejbCreate(-)?Sinuosity
The purpose was to inform the client if there was a problem with the EJB.Procter
It looks like there is no 100% functional equivalent to ejbCreate in EJB 3. Which in our case means i cannot refactor the EJBs without also having to refactor the frontend. I am still going to accept this answer since the solution atleast solves part of my problem.Procter
D
2

You need to use EJB 3.0 lifecycle callback methods using annotations

@PostConstruct, @PreDestroy, @PostActivate or @PrePassivate

These annotations can go on any method that is public, void and no-arg.

Disallow answered 27/10, 2011 at 19:8 Comment(1)
Doesn't need to be public. Straight from PostConstruct's javadoc: "The method on which PostConstruct is applied MAY be public, protected, package private or private." docs.oracle.com/javaee/5/api/javax/annotation/…Segregationist
T
0

If the client was explicitly handling CreateException thrown by ejbCreate and you want to use EJB 3, then you must be using a stateful session bean. Exceptions from ejbCreate from stateless session beans are not propagated to clients, and entity beans do not support annotations in EJB 3. In that case, you want the @Init annotation:

public interface MyHome extends EJBLocalHome {
  public MyInterface create(int arg) throws CreateException;
}

@Stateful
@LocalHome(MyHome.class)
public class MyBean {
  @Init
  public void init(int arg) throws CreateException {
    if (arg < 0) {
      throw new CreateException();
    }
  }
}
Torquemada answered 28/10, 2011 at 5:55 Comment(11)
Unfortunately then i get a problem with scaling.Procter
What does "with scaling" mean?Torquemada
Stateful beans dont scale very well with a large amount of users.Procter
I don't understand; where you using stateless session beans previously? If so, then your clients would never see CreateException thrown from your ejbCreate method anyway because home.create() for a stateless session bean does not call ejbCreate. So, you can use any exception from PostConstruct (e.g., EJBException), and client behavior would be unchanged.Torquemada
Yes it did. We had code in ejbCreate that would check if the bean had been loaded properly. There was an issue with missing jars and subsequent DuplicateHomeExceptions on WAS6. So we had to check for all classes present in the static initializer and then ejbCreate would check the outcome of that.Procter
I guess you mean it doesnt call ejbCreate every time you 'create' a bean. That is true. It still calls it to populate the pool and thats what i need.Procter
Right, the container doesn't call ejbCreate from home.create, so your claim that "the frontend specifically handles CreateException [thrown from ejbCreate]" is invalid. You can use @PostConstruct and throw whatever exception you want; client behavior will be unchanged.Torquemada
you are wrong. The container does call ejbCreate. Just not on <b>every</b> call to create. But since i throw the CreateException from the first time the container tries to populate the pool there will never be any instances of the bean and yes the client does get a CreateException. See theserverside.com/discussions/thread.tss?thread_id=6632Procter
The EJB container never calls ejbCreate from home.create, but it does call it while populating the pool as you stated. So, if your client code is catching EJBException (or RemoteException) and checking if getCause() is CreateException, then I agree client behavior would be changed, and there is no way to accomplish your goal. Is that what your client code is doing? If so, my apologies, and thanks for the discussion.Torquemada
Never is a bit strong i am sure the Spec allows for the Container to do it. You cant rely on it, but the createException still needs to be propagated wheather or not the Container actually calls ejbCreate. Unfortunately some of the design decisions that we made couple years ago showed lack of understanding of the EJB concept/standard. Right now we are trying to upgrade but we have to do that without interrupting our applications.Procter
You're right; I should have said "the WebSphere Application Server EJB container never calls ejbCreate from SLSB home.create in a user-visible manner" :-). (The only exception is deferred EJB initialization combined with a hard minimum poolSize, which can cause the bean pool to be pre-populated and ejbCreate to be called during first touch of home.create. However, even in this case, the container will catch CreateException and issue CNTR0033E rather than propagating the exception to the caller.)Torquemada

© 2022 - 2024 — McMap. All rights reserved.