I got a method call from a stateless ejb which looks like the following
@Stateless
@Local(MyCrudService.class)
@TransactionAttribute(TransactionAttributeType.MANDATORY)
public class MyCrudServiceBean implements MyCrudService {
@EJB
private CrudService crudService;
@Override
public void writeLogEntry(StatementLog statementLog) {
try {
crudService.execute(statement.getSql());
} catch (Exception e) {
crudService.writeLogEntry(statementLog);
throw new MyApplicationException(e.getLocalizedMessage());
}
}
// ...
}
CrudSerivce:
@Stateless
@Local(CrudService.class)
@TransactionAttribute(TransactionAttributeType.MANDATORY)
@Interceptors(GenericFrepDataBaseUserInterceptor.class)
public class CrudServiceBean implements CrudService {
public static final String PERSISTENCE_UNIT_NAME = "name";
private EntityManager entityManager;
@PersistenceContext(unitName = PERSISTENCE_UNIT_NAME)
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
public void execute(String sqlString) {
Query query = entityManager.createNativeQuery(sqlString);
query.executeUpdate();
}
@Override
public void writeLogEntry(StatementLog statementLog) {
entityManager.persist(entity);
}
// ....
}
Statement is an entity which got an sql which is invalid (like 'invalid sql'). On execution I get the following error
javax.ejb.EJBTransactionRolledbackException: JBAS011469
If I debug this, I can see that this happens in the line with the logging.
I think the problem is, that because I am getting an exception the transaction gets rolled back. Because of that it is not possible to write into the db, because there is no open session anymore. Is this the case? What's best practice then? To manually open a session by myself seems quite ugly to me.