Initial Context Lookup возвращает тот же экземпляр | Внедрить EJB без статуса в Pojo

Я пытаюсь внедрить EJB в POJO, используя поиск по контексту. То, что я ожидаю, это поведение EJB без состояния, которое вы получаете, когда делаете

@EJB annotation 

EJB имеет entityManager, который я получаю из EntityManagerFactory в конструкторе для EJB

        @Stateless
        Class ReprovProcess implements ReprovisioningProcess {
        protected EntityManager em;
        public ReprovProcess(){
        //init em from entityManagerFactory;
        }

        public EntityManager getEm(){
        return em;
        }
        }

        @LocalBinding(jndiBinding = "ReprovProcess/local")
        class interface ReprovisioningProcess {
        }

Затем я смотрю EJB дважды, так что

  • при первом поиске закрываю управляющий

  • и затем при втором поиске я должен увидеть, что EntityManager открыт, так как я ожидаю поведение, подобное EJB без состояния.

Но я этого не наблюдаю. Второй раз я делаю поиск и делаю em.isOpen()Я получаю ложное.

Таким образом, вопрос заключается в следующем: можно ли использовать context.lookup для получения поведения, подобного EJB без сохранения состояния? Если нет, то что можно использовать?

            ReprovisioningProcess pro = (ReprovisioningProcess)                         
            ic.lookup("ReprovProcess/local");
            EntityManager em = pro.getEm();
            System.out.println("Entity Manager State = "+em.isOpen());
            em.close();
            System.out.println("Entity Manager State = "+em.isOpen());

            pro = (NetElementReprovisioningProcess) ic.lookup("ReprovProcess/local");
            em = pro.getEm();
            System.out.println("Entity Manager State = "+em.isOpen());
            em.close();
            System.out.println("Entity Manager State = "+em.isOpen());

Выход

Entity Manager State = true
Entity Manager State = false
Entity Manager State = false
------------- ---------------- ---------------

EntityManager is closed
java.lang.IllegalStateException: EntityManager is closed
at org.hibernate.ejb.EntityManagerImpl.close(EntityManagerImpl.java:97)
at com.cisco.cgms.factoryconfig.reprovision.ReprovisiongGroupTest.testIntialLookup(ReprovisiongGroupTest.java:135)

1 ответ

Вы неправильно поняли лицо без гражданства. Речь не идет о контейнере, обеспечивающем функциональность для возврата экземпляра bean-компонента без сохранения состояния в исходное состояние. Вместо этого разработчик должен следить за тем, чтобы все экземпляры сессионного компонента без сохранения состояния были взаимозаменяемыми. Это означает, что компонент без сохранения состояния никогда не должен иметь состояния, видимого клиенту. В твоем случае getEm нарушает этот контракт.

Контейнер имеет пул экземпляров сессионных компонентов без сохранения состояния. Контейнер принимает решение, какой из этих экземпляров возвращается. Вот почему вы не можете делать какие-либо предположения о том, какой экземпляр возвращается при следующем поиске:

ic.lookup("ReprovProcess/local")

Это может быть экземпляр, который вы только что использовали ранее, это может быть экземпляр, который никогда не использовался ни одним клиентом. Если вам нужно состояние, видимое клиенту, используйте сессионные компоненты с сохранением состояния и сохраняйте ссылку на него.

Подвести итог:

  • Не следует ожидать поведения без сохранения состояния, когда реализация неправильно имеет состояние, видимое клиенту.
  • Нет гарантии, какой экземпляр возвращается из пула.
Другие вопросы по тегам