Container managed transactions in JBoss AS 5.0
objectswitch Dec 5, 2008 5:44 PMJust downloaded the newly released AS 5.0.0 GA with the Naga PojoCache.
I tried to use a @Replicable object in a session bean using CMT, but for some reason the cache isn't honoring the transaction. For comparison, I also manipulated an ordinary entity bean and it worked as expected.
To reproduce, first load your pojocache-service.xml into server/all/deploy. I used the pojocache config directly from the user's documentation (after correcting the syntax error on line 50). The only thing I changed was to instruct it to use the JBoss transaction manager:
<!-- Configure the TransactionManager --> <attribute name="TransactionManagerLookupClass"> org.jboss.cache.transaction.JBossTransactionManagerLookup </attribute>
Upon loading, AS logs:
16:09:56,398 INFO [PojoCacheImpl] PojoCache version: JBossCache 'Naga' 3.0.1.GA 16:09:56,424 INFO [PojoCacheImpl] PojoCache version: JBossCache 'Naga' 3.0.1.GA 16:09:56,477 INFO [PlatformMBeanServerRegistration] JBossCache MBeans were successfully registered to the platform mbean server. 16:09:56,483 WARN [NAKACK] max_xmit_size was deprecated in 2.6 and will be ignored 16:09:56,487 WARN [GMS] join_retry_timeout has been deprecated and its value will be ignored 16:09:56,495 INFO [STDOUT] ------------------------------------------------------- GMS: address is 127.0.0.1:34326 ------------------------------------------------------- 16:09:58,504 INFO [RPCManagerImpl] Received new cluster view: [127.0.0.1:34326|0] [127.0.0.1:34326] 16:09:58,506 INFO [RPCManagerImpl] Cache local address is 127.0.0.1:34326 16:09:58,507 INFO [ComponentRegistry] JBoss Cache version: JBossCache 'Naga' 3.0.1.GA
Here is my POJO object as well as my entity bean for comparison:
@Replicable
public class PojoEntity implements Serializable{
public int id;
public int data;
}
@Entity
@Table(name="myTable")
public class PersistentEntity implements Serializable{
@Id
@Column(name="id")
public int id;
@Column(name="data")
public int data;
}
My bean code is below. I used a stateful bean so I could implement SessionSynchronization to print something and get a warm fuzzy that the transaction manager was doing its thing.
@Stateful(name="container")
@TransactionManagement(TransactionManagementType.CONTAINER)
public class CMT implements CMTInterface, SessionSynchronization {
private static final Integer ID = new Integer(1);
@Resource
private SessionContext ctx;
@PersistenceContext(unitName="myPersist", type=PersistenceContextType.EXTENDED)
private EntityManager entityManager;
private PojoCache cache; // Question: Is it possible to inject this resource??
public CMT() {
MBeanServer server = MBeanServerLocator.locateJBoss();
ObjectName on = null;
try {
on = new ObjectName("jboss.cache:service=PojoCache");
} catch (MalformedObjectNameException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NullPointerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
PojoCacheJmxWrapperMBean cacheWrapper = (PojoCacheJmxWrapperMBean) MBeanServerInvocationHandler
.newProxyInstance(server, on, PojoCacheJmxWrapperMBean.class,false);
cache = cacheWrapper.getPojoCache();
cache.start(); // Question: Is it necessary to start cache??
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void createEntity() {
// Entity Bean
PersistentEntity pe = new PersistentEntity();
pe.id = ID;
pe.data = 0;
entityManager.persist(pe);
// Pojo Cache
PojoEntity po = new PojoEntity();
po.id = ID;
po.data = 0;
cache.attach(ID.toString(), po);
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void printEntity() {
// Entity Beqan
PersistentEntity pe = entityManager.find(PersistentEntity.class,ID);
System.out.println("Entity Bean: " + pe.hashCode() + " data: " + pe.data);
// Pojo Cache
PojoEntity po = (PojoEntity) cache.find(ID.toString());
System.out.println("Pojo Cache: " + po.hashCode() + " data: " + po.data);
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void modifyEntity(boolean abortIt) {
// Entity Beqan
PersistentEntity pe = entityManager.find(PersistentEntity.class,ID);
pe.data++;
// Pojo Cache
PojoEntity po = (PojoEntity) cache.find(ID.toString());
po.data++;
if (abortIt) {
ctx.setRollbackOnly();
}
}
public void afterBegin() throws EJBException, RemoteException {
System.out.println("After Begin");
}
public void afterCompletion(boolean arg0) throws EJBException,
RemoteException {
System.out.println("After Completion: commit=" + arg0);
}
public void beforeCompletion() throws EJBException, RemoteException {
System.out.println("Before Completion");
}
}
When I call the following from a local client bean:
container.createEntity(); container.printEntity(); container.modifyEntity(false); container.printEntity(); container.modifyEntity(true); container.printEntity();
I observe the correct rollback in the entity bean but not in the POJO cache:
16:37:52,429 INFO [STDOUT] After Begin 16:37:52,430 INFO [STDOUT] Entity Bean: 859376458 data: 0 16:37:52,430 INFO [STDOUT] Pojo Cache: 1811335439 data: 0 16:37:52,430 INFO [STDOUT] Before Completion 16:37:52,431 INFO [STDOUT] After Completion: commit=true 16:37:52,431 INFO [STDOUT] After Begin 16:37:52,432 INFO [STDOUT] Before Completion 16:37:52,434 INFO [STDOUT] After Completion: commit=true 16:37:52,434 INFO [STDOUT] After Begin 16:37:52,435 INFO [STDOUT] Entity Bean: 859376458 data: 1 16:37:52,435 INFO [STDOUT] Pojo Cache: 1811335439 data: 1 16:37:52,435 INFO [STDOUT] Before Completion 16:37:52,436 INFO [STDOUT] After Completion: commit=true 16:37:52,436 INFO [STDOUT] After Begin 16:37:52,437 INFO [STDOUT] After Completion: commit=false 16:37:52,438 INFO [STDOUT] After Begin 16:37:52,444 INFO [STDOUT] Entity Bean: 1659856006 data: 1 16:37:52,444 INFO [STDOUT] Pojo Cache: 1811335439 data: 2 16:37:52,444 INFO [STDOUT] Before Completion 16:37:52,445 INFO [STDOUT] After Completion: commit=true
Note the bean is rolled back, the POJO cached object is not.
Hopefully I've justed missed some configuration here. Can anyone help me understand how to get the @Replicable object attached to the current transaction?