1

CMTをJPAEntityManagersおよびEJBで動作させようとしましたが、以下のエラーが発生しました。(スタックトランスは切り捨てられます):

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}

私のクラス:

セッション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
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);
}

ステートレスセッションBeanの定義:

@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;
    }
}

ファイル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>

「参照を解決できません」と表示されている場合、他にどこでBeanを定義できますか?ejb-jar.xmlはEJB3では必要ありません。私が見逃している他の設定ファイルはありますか?


アップデート:

  • 上記のコードセグメントを更新して、以下の回答のように、代わりにBeanがインターフェイスタイプとして作成されるようにしました。

  • EJBはweb.xmlで定義またはマップする必要がありますか?

  • web.xmlで参照が必要であると想定して、web.xmlにEJB参照を追加しましたが(以下を参照)、新しいエラーが発生します(以下を参照)。

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>

現在受信中の新しいエラーメッセージ:

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

アップデート:

「ローカル」インターフェースは問題なく機能します(つまり、リモートである必要はありません)

Eclipse内のエンタープライズアプリケーションプロジェクト内にデプロイすることで、それを機能させることができました。web.xml、ejb-jar.xml、またはapplication.xml内でBeanへの参照は必要ありません。

JbossにデプロイされているEAR内のapplication.xmlの内容:

<?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クラス:

@Stateless
@Local(SessionBeanLocal.class)

public class SessionBean implements SessionBeanLocal {

@PersistenceContext(unitName="JPAtestProjectPersistenceUnit")
private EntityManager em;

インターフェイスクラス:

@Local
public interface SessionBeanLocal {

TestTiger addTestTiger(String testTigerName);

物事を機能させる最も重要な変更:セッションを保持するクラス内でローカル変数があり、コンテナー(JBoss AS)が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;
}
4

3 に答える 3

1

Beanではなくリモートインターフェースを注入する必要があります

public class SearchActionExample extends Action {
    @EJB
    private static TestBean2Remote testBean;
于 2011-03-22T08:02:36.297 に答える
0
public class SearchActionExample extends Action {
    @EJB
    private static TestBeanServiceInterface testBean;

静的フィールドへのインジェクションは行わないでください。インジェクションはインスタンスメンバーであり、オブジェクトが作成されたときに発生しますが、静的フィールドはクラスメンバーです。これがおそらく例外の原因です。

于 2011-03-29T04:20:45.780 に答える
0

私は実用的な解決策を手に入れました:

@Localインターフェースは問題なく機能します(つまり、リモートである必要はありません)

web.xml、ejb-jar.xml、application.xml、またはjboss設定ファイル内でBeanへの参照は必要ありません。

Eclipse内の「エンタープライズアプリケーションプロジェクト」(EAP)内にデプロイすることで機能するようになりました。このプロジェクトには、JPAエンティティクラスを含む.jarを含む「DeploymentAssembly」と、他のビジネスロジッククラスを含む別の.jarが含まれています。EAPには、これら2つのプロジェクトに加えてEJBプロジェクトと「動的Webプロジェクト」(.warを作成)があり、ビルドパス上に合計4つのプロジェクトがあります。Eclipse内のJbossASツールは、EAPをJbossサーバーに公開/デプロイします。JbossにデプロイされているEAP内のapplication.xmlの内容:

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

ローカルインターフェイスクラス:

package com.myproject.beans;
import javax.ejb.Local;

import com.myproject.entities.Lion;

@Local
public interface SessionBeanLocal {
Lion addLion(String lionName);
}

SessionBeanクラス:

package com.myproject.beans;

import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import com.myproject.Lion;

@Stateless
@Local(SessionBeanLocal.class)
public class SessionBean implements SessionBeanLocal {

@PersistenceContext(unitName="PersistenceUnitNameInPersistenceXML")
private EntityManager em;

public Lion addLion(String lionName) {
    Lion lion = new Lion(lionName);
    em.persist(lion);
}

物事を機能させる最も重要な変更:セッションを保持するクラス内は可変でした(たとえば、Strutsアクションサーブレット内ですが、任意のサーブレットである可能性があります)、コンテナー(JBoss AS)がBeanを作成するためにsetterメソッドが必要でした:

@EJB()
private SessionBeanLocal bean;

public void setBean(SessionBeanLocal bean) {
    System.out.println("setBean setter was called by container (e.g. Jboss)");
    this.bean = bean;
}

public exampleStrutsServletMethod(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
    PrintWriter out = response.getWriter();

    Lion lion = bean.addLion("Simba");  // this will persist the Lion within the persistence-context (and auto-generate an Id), and the container will manage when it's flushed to the database

    out.print("<html>LION ID = " + lion.getLionId() + "<html>");
}

ファイル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="PersistenceUnitNameInPersistenceXML" transaction-type="JTA">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>java:/MySqlDS</jta-data-source>
    <properties>
    </properties>   
</persistence-unit>

mysql-dx.xml(ディレクトリjboss-server-dir / server / default / deploy内):

<?xml version="1.0" encoding="UTF-8"?>
<datasources>
    <local-tx-datasource>
        <jndi-name>MySqlDS</jndi-name>
        <connection-url>jdbc:mysql://localhost:3306/myProjectDatabase</connection-url>
        <driver-class>com.mysql.jdbc.Driver</driver-class>
        <user-name>username</user-name>
        <password>mypassword</password>
        <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
        <metadata>
            <type-mapping>mySQL</type-mapping>
        </metadata>
    </local-tx-datasource>
</datasources>

注:Eclipse JPAプロジェクトの「JavaPersistence」プロジェクトプロパティパネルで「PersistenceClassManagement」が「Discoverannotatedclassesautomatically」に設定されている場合、クラスをpersistence.xmlで(「<class>」を介して)定義する必要はありません(つまり、JPA 2.0エンティティクラスとpersistence.xmlをコンテナ化するプロジェクト)

注:このソリューションは、EJB3.1、Eclipse Helios SR2、Hibernate 3.6、JPA 2.0、JBoss 6、MySQL5.5.10に基づいています。

注:「コンテナ管理トランザクション」(CMT)について。Hibernateマニュアルはそれらを参照しており、「hibernate.transaction.factory_class」などのpersistence.xmlプロパティを「org.hibernate.transaction.CMTTransactionFactory」の値に設定する必要があることを示しています。これは、ネイティブ休止状態の代わりにJPAEntityManagerを使用している場合には当てはまりません。私はpersistence.xmlにそのようなカスタムCMTプロパティを必要としませんでした。これは、Hibernateを実装する2つの方法(つまり、SessionFactoryとEntityManager)の間で混乱するところです。私はまだ頭を包み込んでいるので、私のソリューションのこの部分についてもっとコメントしてください!意思

于 2011-03-30T01:25:56.407 に答える