NOTE: Adding this question in short form with an answer after spending far more time than I'd like to admit on finding the cause. Hopefully I'll save someone else some pain.
When delegating a method call to an EJB
annotated with @Singleton
, the container throws an Exception along the lines of:
TransactionRolledbackLocalException Client's transaction aborted
The Singleton bean has no data access occurring.
ServiceBeanImpl.java
@Stateless
@Local
public class ServiceBean extends BaseBean{
@EJB private CacheService cacheService;
public FooObj getFooFromCache(int id) {
FooObj fooObj = (FooObj) cacheService.get(id);
if (fooObj == null) {
fooObj = getEntityById(FooObj.class, id);
cacheService.put(id, fooObj); //This throws exception
}
return cacheService.get(id);
}
}
CacheServiceImpl.java
@Singleton
@Startup
public class CacheServiceImpl implements CacheService {
private Cache cache;
@PostConstruct
public void init() {
CacheManager instance = CacheManager.getInstance();
cache = instance.getCache("cache");
}
@PreDestroy
public void destroy() {
CacheManager.getInstance().shutdown();
}
public Object get(Object id) {
return cache.get(id);
}
public void put(Object id, Object obj) {
return cache.put(id, obj);
}
}
Question Why would calling a Singleton bean that does no data access throw a Transaction exception?