Wie zu verwenden Container Managed Transaction (CMT) mit JBoss AS 6, Hibernate 3.6, JPA, JTA und EJB3
Ich versuche zum einrichten einer web-app mit CMT. Ich habe es läuft standalone Eclipse ok, und jetzt versuche ich, um es arbeiten innerhalb der Jboss AS 6, unter Verwendung von Struts 1.0. Ich habe mich entschieden CMT weil die doco, die ich gelesen habe Hinweise, dass es die beste und "zuletzt ausführlich zu nutzen". So scheint, wie contempory/good-practice-Nutzung von Hibernate 3.6.
Kann ich Objekte laden aus einer MySQL-Datenbank mit dem folgenden code-Auszüge, aber gespeicherte Objekte werden nicht geleert/synchronisiert/gespeichert in der Datenbank:
Innerhalb von Struts 1.0 Action Klasse:
InitialContext ctx = new InitialContext();
EntityManagerFactory emf = (EntityManagerFactory)ctx.lookup("java:/MyEntityManagerFactory");
'emf' ist dann an eine Methode übergeben, die mit meiner DAO-Klasse, die nachstehend zusammengefasst ist:
@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
}
Inhalt 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>
Dem Hibernate EntityManager Dokumentation hat eine sehr eingeschränkte Beschreibung, wie die Umsetzung CMT:
Unserer entity-manager/transaction management idiom für CMT und EJB3-container-Nutzung reduziert:
//CMT idiom, durch Injektion
@PersistenceContext(name="Probe") EntityManager em;
Und diese jboss.org Artikel sagt:
Transaktion Abgrenzung mit EJB/CMT
Unser Ziel ist wirklich zu entfernen, transaction demarcation code aus dem data access code:
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void doSomeWork() {
//Do some work
factory.getCurrentSession().load(...);
factory.getCurrentSession().persist(...);
}
Meine Fragen:
-
In der Zeile "actory.getCurrentSession().load(...);", was für ein Typ ist "factory", und wie erstelle ich es? Ist es Hibernate.SessionFactory? Oder einem Jboss-oder HTTP-Sitzung?
-
In der Zeile "@PersistenceContext(name="Probe") EntityManager em;" was ist "name" beziehen? Ich fand ein Beispiel in einem forum, etwas mit "unitName" statt "name". Ist diese Linie, wie ich zuerst deklarieren Sie die Objekt EntityManager, dass ich verwenden, um anzurufen .anhalten() .finden (), etc? (und damit mein code, der erstellt eine EntityManagerFactory ist nicht erforderlich)
-
Sollte ich überlegen, recherchieren und mit "Java Context and Dependency Injection" (CDI)?
Jede Hilfe sehr geschätzt. Bitte lassen Sie mich wissen, was die anderen bits von code oder config-Dateien, die ich liefern sollte,
Update:
Wenn ich nicht verwenden EntityManagerFactory und abrufen eines EntityManager statt mit @PersistenceContext, dann sollte etwas wie in diesem code für mein "session-bean" (die Klasse retriving+speichern von Entitäten, die auf einer pro-Benutzer-Sitzung-basis) werden die Art und Weise, es zu tun?
@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();
}
Wenn das auf die richtige Spur, was benötigt wird persistence.xml? Von all meinem Lesen von doco und die web-ich bin nicht sicher, wo diese erforderlich sein könnten:
<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"/>
InformationsquelleAutor willtardy | 2011-03-21
Du musst angemeldet sein, um einen Kommentar abzugeben.
1) Die Antwort ist in der gleichen Dokument, das du verlinkt 🙂
2) Die
name
ist ein Verweis auf den angegebenen Namen in der tag -persistence-unit
von Ihrempersistence.xml
. In deinem Fall ist esmyPersistanceUnitName
.3) ja, wenn Sie verstehen, dass es nicht bedeutet, etwas zu ersetzen, es soll erleichtern, den Verbrauch von "Bohnen" (die Ressourcen aus der ALS).
Beachten Sie auch, dass, um ein managed EntityManager (mit Vorteile), sollte man nicht die EntityManagerFactory aus der ALS. Sollten Sie sich den EM selbst. Wie du bereits erwähnt hast, es ist so:
Nur in Dinge, die es verwaltet, ALS, wie Servlets, andere CDI-beans, EJB, ... Nicht sicher, ob Struts Action-Klassen würde ihn injiziert 🙂
Für Ihre neueren Fragen: ich würde sagen, dass der am häufigsten verwendete Ansatz ist, lassen Sie die container verwalten der Transaktionen. Jedes EJB-Methodenaufrufs ist verpackt in einer Transaktion vom container, wenn Sie nicht ausdrücklich etwas anderes bestimmt ist. Das ist der häufigste Anwendungsfall. Unter den Motorhauben, verwendet, JTA, und die Transaktion Kontext "erweitert", um JPA-Transaktionen, und Sie müssen nicht angeben, so etwas in Ihrem code zu nutzen. Wieder, geben Sie nur, wenn die default-Verhalten wird nicht gewünscht.
Verstanden, wie der container Transaktionen zu verwalten. Der EntityManager erklärt, nachdem @PersistenceContext ist null, und ich kann nicht herausfinden, warum. Ich habe add '@EJB', versucht "=name" anstelle von "=unitName", aber kein Glück.
Nur WARNEN Nachrichten in der STDOUT: "[org.hibernate.ejb.Ejb3Configuration] Persistenz-provider Anrufers nicht implementiert die EJB3-Spezifikation korrekt.PersistenceUnitInfo.getNewTempClassLoader() ist null." und "[org.hibernate.impl.SessionFactoryObjectFactory] InitialContext nicht implementiert EventContext".
HINWEIS: diese Fehler auch auftreten, die in dieser person die Frage, die bleibt auch un-gelöst: stackoverflow.com/questions/4319362/...
InformationsquelleAutor jpkrohling
Ich habe auch dieses Problem. Ich habe es eingeengt zu werden, wenn mit
@WebService
und wir Spritzen den EntityManager per@PersistenceContext
, der entitymanager null ist.Auch wenn wir delegieren die Daten Zugriff zu einem DAO und fügen Sie den
@TransactionAttribute(TransactionAttributeType.MANDATORY)
für die DAO-Klasse, wirft Sie dasjavax.ejb.EJBTransactionRequiredException
.Frage mich, ob dies ein JBoss-bug, der nicht den stateless session beans, die
@WebService
Anmerkungen zu einer container managed transaction.Danke für deinen Beitrag. War ich nicht mit @WebService-überall obwohl, so können Sie bitte erklären, wie Sie denken, sind Problem ähnlich ist? Und auch, was empfehlen Sie ich tun, um mein problem zu lösen?
InformationsquelleAutor traviskds