Wie man Container Managed Transactions (CMT) arbeiten mit EJB 3.1, Hibernate 3.6, JPA 2.0 , JBoss und MySQL
Ich habe versucht, CMT arbeitet mit JPA-EntityManagers und EJBs, aber es kam nur der Fehler unten. (stack-trance gekürzt):
Caused by: java.lang.RuntimeException: **Could not resolve @EJB reference: [EJB Reference: beanInterface 'com.mydomain.beans.TestBean2', beanName 'testBean2', mappedName 'null', lookupName 'null',** owning unit 'AbstractVFSDeploymentContext@2008455195{vfs:///Users/willtardy/Documents/workspace/.metadata/.plugins/org.jboss.ide.eclipse.as.core/JBoss_6.0_Runtime_Server1300532851414/deploy/mydomainWeb.war}']
for environment entry: env/com.mydomain.action.SearchAction/testBean in unit AbstractVFSDeploymentContext@2008455195{vfs:///Users/willtardy/Documents/workspace/.metadata/.plugins/org.jboss.ide.eclipse.as.core/JBoss_6.0_Runtime_Server1300532851414/deploy/mydomainWeb.war}
Meine Klassen:
Servlet, das den Zugriff auf die Session-Bean:
public class SearchActionExample extends Action {
@EJB
private static TestBeanServiceInterface testBean;
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
testBean.addSource("TEST SOURCE NAME", 88, 99);
Service service = testBean.findService("HBA", "MEL");
return mapping.findForward("success");
}
}
Remote-interface:
@Remote
public interface TestBeanServiceInterface {
//Source is my own custom entity
void addSource(String sourceName, int newthreadsleeptime, int maxactivehttpclients);
//Service is my own Custom entity
Service findService(String departureAirportCode, String arrivalAirportCode);
}
Stateless Session-Bean definition:
@Stateless
public class TestBeanService implements TestBeanServiceInterface {
@PersistenceContext(unitName="mydomainJPA")
private EntityManager em;
public void addSource(String sourceName, int newthreadsleeptime, int maxactivehttpclients) {
Source source = new Source();
source.setName(sourceName);
source.setNewThreadSleepTime(newthreadsleeptime);
source.setMaxActiveHttpClients(maxactivehttpclients);
em.persist(source);
}
public Service findService(String departureAirportCode, String arrivalAirportCode) {
String queryString = "from Service where departureairportcode = '" + departureAirportCode + "' and arrivalairportcode = '" + arrivalAirportCode + "'";
Service service = (Service)em.createQuery(queryString).getSingleResult();
return service;
}
}
Datei persistnce.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence 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_2_0.xsd" version="2.0">
<persistence-unit name="mydomainJPA" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/MySqlDS</jta-data-source>
<class>com.mydomain.entities.Service</class>
<class>com.mydomain.entities.Source</class>
<properties>
<property name="hibernate.query.factory_class" value="org.hibernate.hql.classic.ClassicQueryTranslatorFactory"/>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
<property name="hibernate.current_session_context_class" value="jta"/>
</properties>
</persistence-unit>
Wenn er sagt "cannot resolve Referenz", wo kann ich definieren, die Bohnen? ejb-jar.xml erforderlich ist nicht mit EJB3. Gibt es eine andere config-Datei, die mir fehlt?
UPDATE:
-
Habe ich aktualisiert, der code-Segmente oben, so dass die bean erstellt die interface-Typ statt, wie in der Antwort unten.
-
Tun die EJBs definiert werden müssen oder abgebildet in web.xml?
-
Unter der Annahme, dass eine Referenz erforderlich web.xml, ich habe ein EJB-ref web.xml (siehe unten), aber jetzt ich erhalte eine neue Fehlermeldung (siehe unten)
Zeilen Hinzugefügt web.xml:
<ejb-ref>
<ejb-ref-name>ejb/TestBeanEJBname</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<home>com.mydomain.action.TestBeanService</home>
<remote>com.mydomain.action.TestBeanServiceInterface</remote>
</ejb-ref>
neue Fehlermeldung jetzt empfangen:
12:11:00,980 ERROR [org.jboss.kernel.plugins.dependency.AbstractKernelController] Error installing to PostClassLoader: name=vfs:///Users/willtardy/Documents/workspace/.metadata/.plugins/org.jboss.ide.eclipse.as.core/JBoss_6.0_Runtime_Server1300532851414/deploy/purejetWeb.war state=ClassLoader mode=Manual requiredState=PostClassLoader: org.jboss.deployers.spi.DeploymentException: java.lang.IllegalStateException: Failed to find ContainerDependencyMetaData for interface: au.com.purejet.action.TestBeanServiceInterface
Caused by: java.lang.IllegalStateException: Failed to find ContainerDependencyMetaData for interface: com.mydomain.action.TestBeanServiceInterface
at org.jboss.deployment.MappedReferenceMetaDataResolverDeployer.resolveEjbInterface(MappedReferenceMetaDataResolverDeployer.java:1255) [:6.0.0.Final]
at org.jboss.deployment.MappedReferenceMetaDataResolverDeployer.resolveEjbRefs(MappedReferenceMetaDataResolverDeployer.java:1099) [:6.0.0.Final]
at org.jboss.deployment.MappedReferenceMetaDataResolverDeployer.resolve(MappedReferenceMetaDataResolverDeployer.java:807) [:6.0.0.Final]
at org.jboss.deployment.MappedReferenceMetaDataResolverDeployer.internalDeploy(MappedReferenceMetaDataResolverDeployer.java:181) [:6.0.0.Final]
... 39 more
Update:
"Lokale" Schnittstelle funktioniert einwandfrei (also nicht Remote)
Ich habe es auf Arbeit durch die Bereitstellung innerhalb einer Enterprise-Application-Projekts in Eclipse. Keine Verweise auf Bohnen sind verpflichtet, im Rahmen web.xml, ejb-jar.xml oder application.xml.
Inhalt application.xml in-EAR-Bereitstellung auf Jboss:
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:application="http://java.sun.com/xml/ns/javaee/application_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" id="Application_ID" version="6">
<display-name>myprojects</display-name>
<module>
<web>
<web-uri>myproject.war</web-uri>
<context-root>myproject</context-root>
</web>
</module>
<module>
<ejb>myprojectsEJB.jar</ejb>
</module>
</application>
SessionBean-Klasse:
@Stateless
@Local(SessionBeanLocal.class)
public class SessionBean implements SessionBeanLocal {
@PersistenceContext(unitName="JPAtestProjectPersistenceUnit")
private EntityManager em;
Interface-Klasse:
@Local
public interface SessionBeanLocal {
TestTiger addTestTiger(String testTigerName);
WICHTIGSTE änderung, die Dinge zu arbeiten: in der Klasse, hält der Sitzung wurde die lokale variable eine Einstellung war erforderlich, um die container (JBoss AS) zum erstellen der bean:
@EJB()
private TestBean3Local beanVariable;
public void setBeanVariable(TestBean3Local beanVariable) {
System.out.println("=====\n\nSET BEAN VARIABE SETTER WAS CALLED. (BY CONTAINER?) \n\n=======");
this.beanVariable = beanVariable;
}
InformationsquelleAutor willtardy | 2011-03-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
Müssen Sie injizieren remote-interface und nicht die Bohne
Brauche ich zum definieren der EJB in web.xml?
Hängt davon ab. Wie sind Sie mit der Verpackung die ganze show? Wenn .Krieg und ejb-jar-in .Ohr, sollte alles in Ordnung sein. Wenn die ejbs sind in einer anderen Implementierung, die Sie wahrscheinlich benötigen, um als Präfix den Namen der app, und in der Tat fügen Sie diese an die @EJB-annotation.
Ich mache das nicht jede Verpackung. Ich habe 3 Projekte in Eclipse: 1. ist eine JPA-Projekt mit Entitäten. 2. Projekt enthält DAO und business-Objekt-Klassen, 3. ist die Web/Servlet-Projekt, das derzeit enthält die bean-Klassen. Ich bin mit JBoss inside Eclipse, JBoss-tools. Bis jetzt hatte ich noch nicht zu tun, keine Verpackung, da wir ja noch in der Aufbauphase. Was meinst du mit "ejb-jar"? Brauche ich eine ejb-jar.xml Datei? (Ich habe nicht ein im moment). Wenn die Verpackung ein Thema ist, wäre es schlecht-Praxis zu haben, ein Eclipse-Projekt für EJBs, Servlets, jsps-und Entity-Klassen?
InformationsquelleAutor Heiko Rupp
Nicht tun Injektionen in statische Feld, Injektionen Instanz Mitglieder und passieren, wenn Objekt erstellt wird, in der Erwägung, dass statisches Feld ist ein Klasse Mitglied. Dies ist wahrscheinlich die Ursache für die Ausnahme.
es ist allgemein bekannt, dass Injektionen muss nicht statisch sein und muss g/s-wenn die erklärt pivate. Auch wenn es funktioniert mit statischen, es sollte geändert werden, man weiß nie, welche Folgen es in der Zukunft haben werden. Und, offen gesagt das sprechen, ich verstehe nicht ganz, status Ihrer Frage. Wenn es von Ihnen gelöst, dann bitte posten Sie Ihre eigenen Antwort, es wird helfen, andere Menschen SO, wenn Sie sich treffen, die ähnliche oder das gleiche problem.
du hast Recht, es war falsch, zu "statisch", und in der Tat klappte es nicht mit statischen, das war ein Tippfehler. Ich habe eine Antwort - bitte Lesen Sie es für mich zu vergewissern, dass es Sinn macht und korrekt ist! cheers,
warum nicht? Es akzeptieren und willkommen! (sorry für die Verspätung, war ein wenig beschäftigt)
InformationsquelleAutor Osw
Ich erhalten haben, eine funktionierende Lösung:
@Local-Schnittstelle funktioniert einwandfrei (also nicht Remote)
Keine Verweise auf Bohnen sind verpflichtet, im Rahmen web.xml, ejb-jar.xml, application.xml oder jede jboss config-Datei.
Ich habe es auf Arbeit durch die Bereitstellung innerhalb einer "Enterprise Application-Projekt" (EAP) innerhalb von Eclipse. Dieses Projekt enthält "Deployment Assembly" enthält .Dose mit JPA Entity Klassen, und anderen .jar mit anderen business-Logik-Klassen. Der EAP hat diese zwei Projekte PLUS die EJB-Projekt und die "Dynamic Web Project" (erzeugt ein .Krieg) für insgesamt 4 Projekte auf es zu bauen Weg. Jboss ALS tool in Eclipse veröffentlicht/setzt die EAP auf dem Jboss-server. Inhalt application.xml innerhalb von EAP eingesetzt, Jboss:
Lokale Schnittstelle der Klasse:
SessionBean-Klasse:
WICHTIGSTE änderung, die Dinge zu arbeiten: in der Klasse, das hält die session-variable wurde (z.B. innerhalb einer Struts action servlet, sondern könnte eine beliebige servlet), eine setter-Methode war erforderlich, um die container (JBoss AS) zum erstellen der bean:
Datei persistnce.xml:
mysql-dx.xml (im Verzeichnis jboss-server-Verzeichnis/server/default/deploy):
HINWEIS: die Klassen müssen nicht definiert werden persistence.xml (per "< Klasse >"), wenn "Persistent Class Management" die Option "Discover annotated classes automatically" in "Java Persistence" - Projekt Eigenschaftsfenster für die Eclipse-JPA-Projekt (D. H. das Projekt, dass die Container Ihre JPA-2.0-Entity-Klassen und persistence.xml)
HINWEIS: Diese Lösung basiert auf: EJB3.1, Eclipse Helios SR2, Hibernate 3.6, JPA 2.0, JBoss 6, MySQL 5.5.10
HINWEIS: Über "Container-Managed Transactions" (CMT). Die Hibernate-Handbuch die Sie verweist, und zeigt an, dass Sie benötigen, um persistence.xml Eigenschaften wie "hibernate.die Transaktion.factory_class" , Wert: "org.hibernate.die Transaktion.CMTTransactionFactory". Ist dies nicht der Fall, wenn Sie mithilfe von JPA-EntityManager anstelle der nativen hibernate. Ich wusste nicht, benötigt ein solcher benutzerdefinierter CMT-Eigenschaften in persistence.xml. Dies ist, wo Hibernate verwirrend, zwischen den beiden Möglichkeiten, es zu implementieren (d.h. SessionFactory vs EntityManager). Bitte fühlen Sie sich frei, einen Kommentar mehr zu diesem Teil meiner Lösung, da ich immer noch Umhüllung meinem Kopf herum! Wird
InformationsquelleAutor willtardy