I'm attempting to setup a web app using CMT. I've got it running standalone within Eclipse ok, and now I'm trying to get it working within Jboss AS 6, using Struts 1.0. I've chosen CMT because the doco I've read hints that it's the best and "least verbose to use". So seems like contempory/good-practice use of Hibernate 3.6.
I can load objects from a MySQL database with the following code extracts, but persisted objects are not being flushed/synchronised/saved to the database:
From within Struts 1.0 Action class:
InitialContext ctx = new InitialContext();
EntityManagerFactory emf = (EntityManagerFactory)ctx.lookup("java:/MyEntityManagerFactory");
'emf' is then passed to a method with my DAO class that is summarised below:
@PersistenceContext(unitName="purejetJPA") EntityManager em;
@TransactionAttribute(TransactionAttributeType.REQUIRED)
exampleMethodInMyCustomDAOClass() {
EntityManager em = emf.createEntityManager();
em.find(MyCustomEntity.class, 542); // works successfully
em.persist(newInstanceOfMyCustomEntity); // this executes ok and generates an ID
// however the entity is not saved to database upon completion
}
Contents of persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="myPersistanceUnitName" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/MySqlDS</jta-data-source>
<class>my.custom.entity.Classes</class>
<properties>
<property name="jboss.entity.manager.factory.jndi.name" value="java:/MyEntityManagerFactory"/>
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
<property name="hibernate.connection.autocommit" value="false"/>
<property name="hibernate.current_session_context_class" value="jta"/>
</properties>
</persistence-unit>
</persistence>
The Hibernate EntityManager documentation has a very limited description of how to achieve CMT:
Our entity manager/transaction management idiom for CMT and EJB3 container-use is reduced to this: //CMT idiom through injection @PersistenceContext(name="sample") EntityManager em;
And this jboss.org article says:
Transaction demarcation with EJB/CMT
Our goal really is to remove any transaction demarcation code from the data access code:
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void doSomeWork() {
// Do some work
factory.getCurrentSession().load(...);
factory.getCurrentSession().persist(...);
}
My questions:
In the line "actory.getCurrentSession().load(...);", what type is "factory", and how do I create it? Is it Hibernate.SessionFactory? Or a Jboss or HTTP session?
In the line "@PersistenceContext(name="sample") EntityManager em;" what is "name" referring to? I found an example on a forum of something using "unitName" instead of "name". Is this line how I first declare the EntityManager object that I use to call .persist() .find() etc? (and therefore my code that creates an EntityManagerFactory is not needed)
Should I consider researching and using "Java Context and Dependency Injection" (CDI)?
Any help much appreciated. Please let me know what other bits of code or config files I should supply
Update:
If I don't use EntityManagerFactory, and retrieve an EntityManager instead using @PersistenceContext, then should something like this code for my "session bean" (the class retriving+saving entities on a per-user-session basis) be the way to do it?
@Stateful
@TransactionManagement(value=TransactionManagementType.BEAN)
public class X implements IX {
@PersistenceContext(unitName="MySQL", type=PersistenceContextType.EXTENDED)
private EntityManager em;
@Resource
private UserTransaction tx;
public void doStuff() {
tx.begin();
em.joinTransaction();
em.find(myEntity);
em.perrsist(myEntity);
tx.commit();
}
If this is on the right track, what is needed in persistence.xml? From all my reading of doco and the web I'm not sure which of these might be required:
<property name="jboss.entity.manager.factory.jndi.name" value="java:/MyEntityManagerFactory"/>
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.CMTTransactionFactory"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
<property name="hibernate.connection.autocommit" value="false"/>
<property name="hibernate.current_session_context_class" value="jta"/>