Pregunta

Estoy tratando de usar gestor de la entidad de hibernación con MySQL y GlassFish. Estoy recibiendo el siguiente error al intentar utilizar un origen de datos JTA:

Caused by: org.hibernate.HibernateException: The chosen transaction strategy requires access to the JTA TransactionManager
        at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:376)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1367)
        at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:858)
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:733)
        ... 37 more

Así es como he configurado mi 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="myPU" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>jdbc/mysql</jta-data-source>
    <class>com.my.shared.entity.MyFile</class>
    <class>com.my.shared.entity.MyRole</class>
    <class>com.my.shared.entity.MyUser</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
      <property name="hibernate.show.sql" value="true" />
    </properties>

Sin embargo, cuando configure un origen de datos no JTA, funciona bien

<?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="myPU" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <non-jta-data-source>jdbc/mysql</non-jta-data-source>
        <class>com.my.shared.entity.MyFile</class>
        <class>com.my.shared.entity.MyRole</class>
        <class>com.my.shared.entity.MyUser</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
          <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
          <property name="hibernate.show.sql" value="true" />
        </properties>
</persistence-unit>
</persistence>

Eso es todo muy bien, pero me gustaría mucho a su uso:

em.persist(myObject);

en lugar de:

em.getTransaction().begin();
em.persist(myObject);
em.getTransaction().commit();

Me estoy perdiendo algo con la configuración de hibernación, o es incluso posible utilizar una fuente de datos JTA?

¿Fue útil?

Solución

Parece que para su configuración, transacciones gestionadas por contenedor se utilizan de forma predeterminada. En este caso es necesario definir un modo de sincronización de transacción para la notificación de la capa de persistencia (y puede actualizar el segundo nivel de caché, por ejemplo). Así que hay que definir manager_lookup_class propiedad de la siguiente manera:

// For GlassFish:
hibernate.transaction.manager_lookup_class=org.hibernate.transaction.SunONETransactionManagerLookup
// For WebSpere:
hibernate.transaction.manager_lookup_class=org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
// For JBoss:
hibernate.transaction.manager_lookup_class=org.hibernate.transaction.JBossTransactionManagerLookup
// For OpenEJB:
hibernate.transaction.manager_lookup_class=org.apache.openejb.hibernate.TransactionManagerLookup

También tiene que marcar métodos de negocio que la capa de datos de acceso como "transaccional". Para que usted necesita para marcarlos con @javax.ejb.TransactionAttribute(REQUIRED) (ver aquí para obtener más información acerca de esta anotación).

También tiene la opción de cambiar a las transacciones de frijol gestionados. Puede hacerlo diciendo:

hibernate.transaction.factory_class=org.hibernate.transaction.JTATransactionFactory

A continuación, el frijol es responsable de iniciar / finalizar la transacción:

org.hibernate.Session session = ...;
org.hibernate.Transaction tx = null;
try {
    tx = session.beginTransaction();
    session.createQuery(...); // do some staff
    tx.commit();
} catch (HibernateException e)
{
    if (tx != null) {
        tx.rollback();
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top