Donnerstag, Juni 4, 2020

hibernate, mysql, glassfish v3 und JTA-datasource

Ich bin versucht, hibernate entity manager mit mysql und glassfish. Ich bekomme folgenden Fehler beim Versuch, die Verwendung einer JTA-datasource:

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

Hier ist, wie ich konfiguriert haben, mein 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>

Allerdings, wenn ich bei der Konfiguration ein non-jta-datasource, es funktioniert gut

<?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>

Das ist alles schön und gut, aber ich würde wirklich wie zu verwenden:

em.persist(myObject);

statt:

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

Bin ich etwas fehlt mit der hibernate-Konfiguration, oder ist es auch möglich die Verwendung einer JTA-datasource?

InformationsquelleAutor KevMo | 2010-03-01

1 Kommentar

  1. 11

    Es scheint, wie für Ihre Konfiguration, container-verwalteten Transaktionen werden standardmäßig verwendet. In diesem Fall müssen Sie definieren eine Art der Transaktion-Synchronisierung, so dass die Persistenz-Schicht mitgeteilt wird (und aktualisieren der 2nd-level cache, zum Beispiel). So müssen Sie definieren, manager_lookup_class Eigenschaft, wie folgend:

    //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

    Auch Sie haben, um business-Methoden, die auf Daten-layer als „transactional“. Für diesen müssen Sie markieren Sie mit @javax.ejb.TransactionAttribute(REQUIRED) (siehe hier für weitere Informationen über diese Anmerkung).

    Haben Sie auch eine option zum Umschalten zu bean-managed Transaktionen. Sie können es tun, indem Sie sagen:

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

    Dann die bean ist verantwortlich für das starten/beenden der Transaktion:

    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();
        }
    }
    • ok, also ich habe <property name=“hibernate.die Transaktion.manager_lookup_class“ value=“org.hibernate.die Transaktion.SunONETransactionManagerLookup“ /> zu meinem persistence.xml. Jetzt ist es „besteht“ ohne eine Fehlermeldung, aber es wird nie an die Datenbank übergeben.
    • Sie brauchen nicht zu strart eine Transaktions-deklarativ wie em.getTransaction().begin();, wie Sie mit CMT. Ich hoffe, Sie haben markiert, Ihr bean-Methode mit @Transactional?
    • Ops, sorry, Sie sind nicht mit Frühling 🙂 Folgen Sie meine Antwort dann.

Kostenlose Online-Tests