Внедрить диспетчер сущностей в несколько bean-компонентов одного класса

У меня есть класс сеансового компонента, который выполняет некоторые операции с базой данных. Мне нужно использовать класс с несколькими базами данных, поэтому я конфигурирую ejb-jar.xml для создания сеансовых компонентов из этого класса, каждый компонент для каждой базы данных. Вот код.

public class UserEM
{
    /** The entity manager */
    @Resource(name="userEntityManager/em")
    private EntityManager em;

    public EntityManager getEntityManager()
    {
        return this.em;
    }

    ... Database operations using the `em` ...
}

А вот ejb-jar.xml

 ...
  <enterprise-beans>
    <session>
      <ejb-name>UserEM1</ejb-name>
      <ejb-class>com.abc.app.dao.UserEM</ejb-class>
      <session-type>Stateless</session-type>

      <persistence-context-ref>
        <persistence-context-ref-name>userEntityManager/em</persistence-context-ref-name>
        <persistence-unit-name>DataSource1</persistence-unit-name>
      </persistence-context-ref>
    </session>
    <session>
      <ejb-name>UserEM2</ejb-name>
      <ejb-class>com.abc.app.dao.UserEM</ejb-class>
      <session-type>Stateless</session-type>

      <persistence-context-ref>
        <persistence-context-ref-name>userEntityManager/em</persistence-context-ref-name>
        <persistence-unit-name>DataSource1</persistence-unit-name>
      </persistence-context-ref>
    </session>
  </enterprise-beans>
</ejb-jar>
...

Когда я создаю только один сеансовый компонент, он работает, как и ожидалось. НО я создаю более двух, он выдает исключение при развертывании как:

Caused by: java.lang.IllegalArgumentException: JBAS011053: Incompatible conflicting binding at java:comp/env/userEntityManager/em source: org.jboss.as.jpa.injectors.PersistenceContextInjectionSource@937b07ef
    at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor.addJndiBinding(ModuleJndiBindingProcessor.java:237)
    at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor.deploy(ModuleJndiBindingProcessor.java:136)
    at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:113) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]

Что здесь происходит. Кто-нибудь может помочь? Любые предложения или замечания принимаются.

Нава


person NawaMan    schedule 05.09.2012    source источник


Ответы (2)


Поиграв с ним некоторое время, я нашел решение. Вот код.

А вот ejb-jar.xml

 ...
  <enterprise-beans>
    <session>
      <ejb-name>UserEM1</ejb-name>
      <ejb-class>com.abc.app.dao.UserEM</ejb-class>
      <session-type>Stateless</session-type>

      <persistence-context-ref>
        <persistence-context-ref-name>userEntityManager/em1</persistence-context-ref-name>
        <persistence-unit-name>DataSource1</persistence-unit-name>
      </persistence-context-ref>
    </session>
    <session>
      <ejb-name>UserEM2</ejb-name>
      <ejb-class>com.abc.app.dao.UserEM</ejb-class>
      <session-type>Stateless</session-type>

      <persistence-context-ref>
        <persistence-context-ref-name>userEntityManager/em2</persistence-context-ref-name>
        <persistence-unit-name>DataSource2</persistence-unit-name>
      </persistence-context-ref>
    </session>
  </enterprise-beans>
</ejb-jar>
...

Чего я не знал, так это того, что здесь мы не только объявляем два EJB, но также объявляем два имени ссылки на контекст сохраняемости, которые должны быть уникальными в приложении. Другое слово, что значение в 'persistence-context-ref-name' также должно быть уникальным. Как только это будет сделано, приложение можно будет развернуть, и будут созданы два сеансовых компонента с разными источниками данных. Компонент можно найти с помощью JNDI.

Ваше здоровье,

person NawaMan    schedule 11.09.2012

Попробуйте изменить @Resource на @PersistenceContext:

@PersistenceContext(name="userEntityManager/em")
private EntityManager em;

Обновление Как насчет внедрения через ejb-jar.xml? Определите EntityManager em без аннотации и добавьте в свой xml следующее:

<session>
  <ejb-name>UserEM1</ejb-name>
  <ejb-class>com.abc.app.dao.UserEM</ejb-class>
  <session-type>Stateless</session-type>
  <persistence-context-ref>
    <persistence-context-ref-name>userEntityManager/em</persistence-context-ref-name>
    <persistence-unit-name>DataSource1</persistence-unit-name>
    <injection-target>   
      <injection-target-class>com.abc.app.dao.UserEM</injection-target-class>   
      <injection-target-name>em</injection-target-name>  
    </injection-target>
  </persistence-context-ref>
</session>

<session>
...
</session>

Я также заметил, что у вас есть два элемента enterprise-beans. Определите только один и определите сеансовые компоненты с элементом сеанса внутри этого.

person Csaba    schedule 05.09.2012
comment
Привет, Чаба, я получил ... Имя единицы сохранения не было указано, и в развертывании приложения ABC-App.war есть 3 определения единицы сохранения. Либо измените приложение, чтобы оно имело только одно определение единицы сохраняемости, либо укажите unitName для каждой ссылки на единицу сохраняемости. :-( - person NawaMan; 06.09.2012
comment
Двойные теги enterprise-beans были ошибкой копирования и вставки. - person NawaMan; 07.09.2012
comment
С вашим отредактированным ответом у меня все еще та же проблема (то же исключение). Спасибо, в любом случае. - person NawaMan; 07.09.2012