[EJB2/EJB3] Constructie stateful session via home interface

Pagina: 1
Acties:

  • ari3
  • Registratie: Augustus 2002
  • Niet online
In EJB2 kon je een stateful session bean als voglt bean initialiseren:
Java:
1
2
3
4
InitialContext context = new InitialContext();
Object obj = (MijnFacadeHome) context.lookup("nl/bedrijf/MijnFacadeHome");
MijnFacadeHome home = (MijnFacadeHome) PortableRemoteObject.narrow(obj, MijnFacadeHome.class);
MijnFacadeBean bean = home.create(initParam1, initParam2);


Hoe doe ik dit nu in EJB3? In EJB3 is het wordt voor het instantiëren van een bean namelijk geen home interface meer gebruikt:
Java:
1
2
InitialContext context = new InitialContext();
MijnFacadeBean bean = (MijnFacadeBean) context.lookup("nl/bedrijf/MijnFacadeBean");


In bovenstaand voorbeeld mis ik dus de mogelijkheid de stateful bean te initialiseren? In de Javadoc zie ik wel een @Init annotatie die blijkbaar een initialisatie methode aanwijst, maar hoe en wanneer wordt deze dan aangeroepen? De Javadoc spreekt van een "adapted Home/LocalHome interface". EJB3 heeft toch geen home interfaces meer?

Als tijdelijke workaround heb ik gewoon een init methode op de sessiebean gezet die dan zo geïnstantieerd wordt:
Java:
1
2
3
InitialContext context = new InitialContext();
MijnFacadeBean bean = (MijnFacadeBean) context.lookup("nl/bedrijf/MijnFacadeBean");
bean.init(initParam1, initParam2);


Deze aanpak is niet wenselijk aangezien men de init-methode kan vergeten. Of erger nog: meer dan eens aanroepen waardoor de gebruikscontext van de bean gereset wordt. Ik wil afdwingen dat de stateful session bean bij creatie geïnitialiseerd wordt.

"Kill one man, and you are a murderer. Kill millions of men, and you are a conqueror. Kill them all, and you are a god." -- Jean Rostand


  • Marcj
  • Registratie: November 2000
  • Laatst online: 01-12 16:59
Als ik het in de Java EE tutorial goed lees, dan wordt de methode die wordt aangegeven met de @PostConstruct annotation direct nadat een statful bean is gemaakt aangeroepen. Ik weet niet of dit is wat je bedoelt?

  • ari3
  • Registratie: Augustus 2002
  • Niet online
Marcj schreef op vrijdag 06 april 2007 @ 12:46:
Als ik het in de Java EE tutorial goed lees, dan wordt de methode die wordt aangegeven met de @PostConstruct annotation direct nadat een statful bean is gemaakt aangeroepen. Ik weet niet of dit is wat je bedoelt?
Nee, bedoel ik niet. In de javadoc voor @PostConstruct staat dat de postconstruct method geen argumenten mag hebben. Ik zoek dus een soort @PostConstruct die wel argumenten accepteert. Volgens mij is dat @Init, maar ik zie dus niet hoe ik de parameters doorgeef als ik geen home interface heb.

"Kill one man, and you are a murderer. Kill millions of men, and you are a conqueror. Kill them all, and you are a god." -- Jean Rostand


  • Marcj
  • Registratie: November 2000
  • Laatst online: 01-12 16:59
Ik het hier nog een iets duidelijkere omschrijving gevonden.
Specifies the correspondence of a method in the bean class with a createMETHOD method for an adapted EJB 2.1 EJBHome or EJBLocalHome client view.

This annotation is used only in conjunction with stateful session beans, or those that have been annotated with the @javax.ejb.Stateful class-level annotation,

The return type of a method annotated with the @javax.ejb.Init annotation must be void, and its parameter types must be exactly the same as those of the referenced createMETHOD method or methods.

The @Init annotation is required only for stateful session beans that provide a Remote-Home or LocalHome interface. You must specify the name of the adapted create method of the Home or LocalHome interface, using the value attribute, if there is any ambiguity.
Het lijkt me dus dat je nog steeds die EJBHome kunt gebruiken en deze kan laten refereren met @Init met eventueel een value dit aangeeft welke methode gebruikt moet worden.

Hier heb ik ook nog een voorbeeld gevonden en daarmee wordt naar een EJBHome verwezen dmv RemoteHome (kan waarschijnlijk ook wel LocalHome zijn).

  • ari3
  • Registratie: Augustus 2002
  • Niet online
Marcj schreef op vrijdag 06 april 2007 @ 14:00:
Het lijkt me dus dat je nog steeds die EJBHome kunt gebruiken en deze kan laten refereren met @Init met eventueel een value dit aangeeft welke methode gebruikt moet worden.

Hier heb ik ook nog een voorbeeld gevonden en daarmee wordt naar een EJBHome verwezen dmv RemoteHome (kan waarschijnlijk ook wel LocalHome zijn).
Inmiddels is het gelukt als volgt:
De local home interface:
Java:
1
2
3
public interface MijnFacadeLocalHome extends EJBLocalHome {
   public MijnFacadeLocal create(Object initParam1, Object initParam2) throws CreateException;
}

De stateful session bean: (merk op dat de signatuur van de create-method niet gelijk hoeft te zijn aan de signatuur in de home interface!)
Java:
1
2
3
4
5
6
7
8
@Stateful
@LocalHome(MijnFacadeLocalHome.class)
public class MijnFacadeBean implements MijnFacadeLocal {
   @Init
   public void create(Object initParam1, Object initParam2) throws CreateException {
      // ...
   }
}

En de client code:
Java:
1
2
3
4
Context context = new InitialContext();
Object obj = context.lookup("context/MijnFacadeBean/localHome");
MijnFacadeLocalHome home = (MijnFacadeLocalHome) PortableRemoteObject.narrow(obj, MijnFacadeLocalHome.class); 
MijnFacadeLocal facade = home.create(initParam1, initParam2);


Hiermee heb ik (deels) bereikt wat ik wilde: een manier om een EJB3 stateful session bean geparametriseerd kunnen instantieëren. Toch de volgende kanttekeningen:

(1) Bovenstaande client voorbeeld is niet ideaal omdat er een dependency is op de JNDI-naam van de localhome interface. Het voorbeeld van Sun gebruikt LocalHome.class.getName() als JNDI-naam, maar dat is blijkbaar applicatieserver-specifiek. Bij het uitproberen kwam ik er achter dat JBoss 4.0.5 de localhome interface op "{persistence-unit-naam}/{bean-naam}/localHome" in de JNDI-boom plaatst.

(2) Het blijft vaag is dat er geen EJB3-manier is om een stateful session bean geparametriseerd te instantieëren. Is dit bewust zo gedaan? Hoewel de hier beschreven workaround met de EJB2 home interface werkt, is het nog steeds mogelijk om MijnFacadeBean te instantiëren zonder dat de @Init create method wordt aangeroepen. De create-methode wordt immers alleen gebruikt als je de bean instantieert middels de home interface. Het lijkt er op dat er geen manier is om geparametriseerde constructie te kunnen afdwingen op een EJB3-achtige manier.

"Kill one man, and you are a murderer. Kill millions of men, and you are a conqueror. Kill them all, and you are a god." -- Jean Rostand