Hello,
I use Hibernate embedded in a SAR with my JBoss Application as rated by the Hibernate's site. I'd like to the Transaction Manager of JBoss instead of the Hibernate's one.
I wrote 3 persistent classes and a EJB Session manipulating them. I told my EJB to use CMT with declaratic transaction. So I told intially that all my transactions are Required. I've tested an example of writing in the database. It didn't work and there was no Exception sent. So I inquired in the Forum and I found someone having the same problem and the solution found was to flush the session. I did it and it works.
However I wanted to see what would happen if the attribute of transactions of the EJB is Notsupported. So I changed it and I launch the same test. THe result is that my EJB wrote also in the Database. I find it strange. I thought as there is no transaction, Hibernate could write data in the Database.
So here's the code of the EJB method called :
Code:
public void getConnectionFactory() throws HibernateException {
Session session = HibernateFactory.getSession("maxdb");
Client cl = new Client();
cl.setNom("Bob");
session.save(cl);
session.flush();
HibernateFactory.closeSession("maxdb");
}
Here's the jboss-service.xml placed in the SAR :
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE server>
<!-- Generated file - Do not edit! -->
<server>
<mbean code="net.sf.hibernate.jmx.HibernateService" name="jboss.jca:service=HibernateFactory">
<depends>jboss.jca:service=RARDeployer</depends>
<depends>jboss.jca:service=LocalTxCM,name=MaxdbDS</depends>
<attribute name="MapResources">mappings/persistent/Client.hbm</attribute>
<attribute name="JndiName">java:/hibernate/HibernateFactory</attribute>
<attribute name="Datasource">java:/MaxdbDS</attribute>
<attribute name="Dialect">net.sf.hibernate.dialect.SAPDBDialect</attribute>
<attribute name="UseOuterJoin">false</attribute>
<attribute name="ShowSql">true</attribute>
<attribute name="UserTransactionName">UserTransaction</attribute>
<attribute name="TransactionStrategy">net.sf.hibernate.transaction.JTATransactionFactory</attribute>
<attribute name="TransactionManagerLookupStrategy">net.sf.hibernate.transaction.JBossTransactionManagerLookup</attribute>
</mbean>
</server>
Here's my datasource configuration file, maxdb-ds.xml :
Code:
<datasources>
<local-tx-datasource>
<jndi-name>MaxdbDS</jndi-name>
<connection-url>jdbc:sapdb://192.168.1.3/COCHISE</connection-url>
<driver-class>com.sap.dbtech.jdbc.DriverSapDB</driver-class>
<user-name>dba</user-name>
<password>dba</password>
</local-tx-datasource>
<attribute name="TransactionManager">java:/TransactionManager</attribute>
</datasources>
Here's the ejb-jar.xml of my EJB :
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"
"http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
<display-name>Hibernate</display-name>
<enterprise-beans>
<session>
<display-name>Hibernate</display-name>
<ejb-name>Hibernate</ejb-name>
<home>HibernateRemoteHome</home>
<remote>HibernateRemote</remote>
<ejb-class>HibernateBean</ejb-class>
<session-type>Stateful</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
<assembly-descriptor>
<container-transaction id="EJB_Deployment_Model__EJB_Container_Transaction1">
<method>
<description>test</description>
<ejb-name>Hibernate</ejb-name>
<method-intf>Remote</method-intf>
<method-name>getConnectionFactory</method-name>
<method-params/>
</method>
<trans-attribute>NotSupported</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
At last here's the HibernateFactory class inspired from HibernateUtil :
Code:
import java.util.HashMap;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
public class HibernateFactory {
private static HashMap factories;
public static final String maxdb = "maxdb";
private final SessionFactory sessionFactory;
public final ThreadLocal session = new ThreadLocal();
static {
factories = new HashMap();
try {
HibernateFactory factory1 = new HibernateFactory("HibernateFactory");
factories.put(maxdb, factory1);
} catch (NamingException e) {
e.printStackTrace();
}
}
private HibernateFactory(String service) throws NamingException{
Context ctx = null;
ctx = new InitialContext();
this.sessionFactory = (SessionFactory) ctx.lookup("java:/hibernate/"+service);
}
public void close() throws HibernateException {
Session s = (Session) session.get();
session.set(null);
if (s != null){
s.close();
}
}
public Session currentSession() throws HibernateException {
Session s = (Session) session.get();
if (s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static Session getSession(String key) throws HibernateException{
HibernateFactory hibFac = (HibernateFactory) factories.get(key);
if (hibFac != null) {
return hibFac.currentSession();
} else {
return null;
}
}
public static void closeSession(String key) throws HibernateException {
HibernateFactory hibFac = (HibernateFactory) factories.get(key);
if (hibFac != null) {
hibFac.close();
}
}
}
Thanks for your precious help