使用Glassfish v4在CMT EJB中进行Hibernate 4.3事务

时间:2014-03-13 21:35:09

标签: hibernate java-ee glassfish jta

我在Glassfish 4上使用Java EE 7和最新的Hibernate 4.3。根据Hibernate文档(http://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch01.html#tutorial-firstapp-helpershttp://docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch13.html#transactions-demarcation-jta)我创建了:

pom.xml依赖项

<dependencies>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version>7.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>4.3.4.Final</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>1.7.6</version>
    </dependency>
    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc6</artifactId>
        <version>11.2.0</version>
    </dependency>
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.6</version>
    </dependency>
</dependencies>

src / main / resources中的hibernate.cfg.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
        <property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
        <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:XE</property>
        <property name="hibernate.connection.username">xxx</property>
        <property name="hibernate.connection.password">xxx</property>
        <property name="hibernate.default_schema">xxx</property>

        <property name="hibernate.current_session_context_class">jta</property>
        <property name="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</property>
        <property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.SunONETransactionManagerLookup</property>

        <mapping class="xxx" />
    </session-factory>
</hibernate-configuration>

HibernateUtil助手类

public class HibernateUtil {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            Configuration configuration = new Configuration().configure();
            StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
            return configuration.buildSessionFactory(serviceRegistry);
        } catch (HibernateException ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

}

和EJB无状态bean

@Stateless
public class AccountBean {
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

    @Transactional
    public List findAll() {
        Session session = sessionFactory.getCurrentSession();
        List accounts = session.createQuery("from Account").list();

        return accounts;
    }
}

但我得到例外:

  

org.hibernate.HibernateException:没有TransactionManagerLookup   指定于   org.hibernate.context.internal.JTASessionContext.currentSession(JTASessionContext.java:85)     在   org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)

只有工作方式是每次都手动启动交易:

public List findAll() {
    Session session = sessionFactory.getCurrentSession();
    session.beginTransaction();
    List accounts = session.createQuery("from Account").list();
    session.getTransaction().commit();

    return accounts;
}

但根据文件,我不想一直写它,因为我不需要。

2 个答案:

答案 0 :(得分:0)

不要使用

     <property name="hibernate.transaction.manager_lookup_class">...</property>

在Hibernate中4.使用类似

的内容
<property name="connection.datasource">jdbc/MyDB</property>
<property name="current_session_context_class">jta</property>
<property name="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory</property>
<property name="hibernate.transaction.jta.platform">org.hibernate.service.jta.platform.internal.SunOneJtaPlatform</property>

答案 1 :(得分:-1)

不要忘记你的EJB:

   @TransactionManagement(TransactionManagementType.CONTAINER)
   @TransactionAttribute(TransactionAttributeType.REQUIRED)