Hi.
I want to have some DAOs , that encapsulate the Query, Entitymanager and
JPA Logic.
E.g. i write a simple DAO:
//my dao is an ejb
@Stateless
public class MyDAOBean implements MyDAO {
//persistence context is handled inside dao, not business logic
@PersistenceContext
protected EntityManager em;
@Override
public MyEntity findMyEntityBySomething(String something) {
return em.createNamedQuery(MyEntity.findBySomething,
MyEntity.class).
setParameter(MyEntity_.something.getName(), something).
getSingleResult();
}
}
Now i want to use this dao from an business logic EJB:
@Stateless
public class MyLogicBean implements MyLogic {
@EJB
private MyDAO myDAO ;
public void doSomething() {
try {
MyEntity myEntity =
myDAO .findMyEntityBySomething(something);
} catch (NoResultException nre) {
//handle nre somehow
}
}
}
So I do not want to handle Runtime Exceptions thrown by
getSingleResult() in my DAO, but in the business logic.
The problem here is, that the catch does not work, because instead of
NoResultException javax.ejb.EJBTransactionRolledbackException is thrown.
javax.ejb.EJBTransactionRolledbackException is caused by
javax.ejb.TransactionRolledbackLocalException which is finally thrown by
javax.persistence.NoResultException.
Is there a way to prevent the ejb container from trying to end the
transaction if leaving a method?
I worked around this issue by removing the @Stateless from DAO and
making a simple POJO:
public class MyDAO {
private EntityManager em;
public void setEntityManager(EntityManager em) {
this.em = em;
}
public MyEntity findMyEntityBySomething(String something) {
return em.createNamedQuery(MyEntity.findBySomething,
MyEntity.class).
setParameter(MyEntity_.something.getName(), something).
getSingleResult();
}
}
than i call it some differt way from business logic:
@Stateless
public class MyLogicBean implements MyLogic {
@Inject
private MyDAO myDAO ;
//PersistenceContext is inside of logic
@PersistenceContext
private EntityManager em;
@PostConstruct
public void init() {
//EntityManager must be provided to dao inside ob logic
myDAO.setEntityManager(em);
}
@Override
public void doSomething() {
try {
MyEntity myEntity =
myDAO .findMyEntityBySomething(something);
} catch (NoResultException nre) {
//handle nre somehow
}
}
}
This way i can catch NoResultException a correct way. But there are two
disadvanteges.
PersistenceContext must be inside of logic class and EntityManager must
be provided to dao inside ob logic throw a setter method.
yours sincerely
Oleg Mayevskiy