The setup is like this:
Front-end: GWT using RequestFactory for sending data objects
Back-end:
Web-layer:
GWT server side code which has injected EJB
EJB-layer:
Stateless sesion beans:
Data access bean (DAB)=> has injected EntityManager for JPA operations and provides methods for merging and retrieving of entities
Facade bean (FB) => calls methods of DAB and is interface between EJB and web layer
When an entity object (lets say MyEntity) is to be saved after it has been modified at the client side, the flow is like this:
1. Initiated by the client
2. Server side GWT code is run and invokes the following methods:
3. The find() method looks up the instance of MyEntity using FB.findMyEntity() which calls DAB.findMyEntity() which in turn uses EntityManager to do the look-up. The find() method must be invoked as its part of RequestFactory flow in GWT.
4. The save() leads to FB.saveMyEntity() --> DAB.saveMyEntity() --> EntityManager.merge() and the changed entity object is persisted.
It is obvious that each of find() and save() methods run in different JPA transaction which is ineffective and bad design.
With regards to keeping the facade bean interface with simple look-up and saving methods:
- What is the best design to handle this situation? - preferably with having both method calls in one
JPAtransaction. - What are alternatives? With pros and cons.
EDIT: Including simplified examples of the code for FB and DAB.
Facade bean (FB):
@Stateless
public class MyFacadeBean implements MyFacade{
@EJB
private DataAccessBean dab;
@Override
public void saveMyEntity(MyEntity entity) {
dab.saveMyEntity(entity);
}
@Override
public void findMyEntity(int id) {
dab.saveMyEntity(id);
}
}
Data access bean (DAB):
@Stateless
public class DataAccesseBean implements DataAccessBeanInterface{
@PersistenceContext
private EntityManager entityManager;
@Override
public void saveMyEntity(MyEntity entity) {
entityManager.merge(entity);
}
@Override
public void findMyEntity(int id) {
entityManager.find(MyEntity.class,id);
}
}