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
JPA
transaction. - 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);
}
}