Сервлет получает пустой объект от удаленного сеансового компонента EJB3

Я уверен, что это ошибка новичка ...

Итак, у меня есть приложение Java EE 6 с сущностями, фасадами (реализующими уровень сохраняемости) и сессионными компонентами без сохранения состояния (EJB3) с удаленными интерфейсами (обеспечивающими доступ к сущностям через фасады).

Это нормально работает. Через SLSB я могу извлекать объекты и управлять ими.

Теперь я пытаюсь сделать это из веб-приложения (развернутого в том же Glassfish, определения сущности + интерфейса из приложения Java EE, импортированные как отдельная банка). У меня есть сервлет, который получает экземпляр внедренного SLSB. Я получаю его для получения объекта, и происходит следующее (я вижу это в журналах):

  • создается экземпляр удаленного SLSB, его метод называется
  • SLSB создает экземпляр фасада, вызывает метод get
  • фасад извлекает экземпляр сущности из БД, возвращает его
  • SLSB returns the instance of the entity to the caller
    • (all is good until here)
  • вызывающий сервлет получает .. пустой экземпляр объекта !!

Что не так? Это должно сработать, правда?

MyServlet:

public class MyServlet extends HttpServlet {

  @EJB
  private CampaignControllerRemote campaignController; // remote SLSB

  protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/plain");
    PrintWriter out = response.getWriter();
    try {
      Campaign c = campaignController.getCampaign(5L); // id of an existing campaign
      out.println("Got "+ c.getSomeString()); // is null !!
    } finally { 
        out.close();
    }
  }
  ...
}

Пожалуйста, дайте мне знать, если вы хотите увидеть другой код, и я обновлю сообщение.


person Hank    schedule 20.04.2010    source источник
comment
Является ли c нулевым объектом или возвращает пустую строку? Отобразили ли журналы, что кампания 5L полностью заполнена в SLSB до того, как вызов вернется к сервлету?   -  person JoseK    schedule 21.04.2010
comment
@josek: c существует, не равно нулю. c.getSomeString() возвращает ноль. Когда SLSB извлекает кампанию "5L", someString заполняется правильно.   -  person Hank    schedule 21.04.2010
comment
Возможно, я ошибаюсь, но думаю, что Glassfish нуждается в удаленных интерфейсах, упакованных в одно и то же веб-приложение.   -  person JoseK    schedule 21.04.2010


Ответы (1)


... о боже, это как-то неловко ...

Оказывается, я игнорировал маленькое приятное предупреждение об использовании Vector как типа поля, которое имеет отношение @xxToMany с FetchType.LAZY:

Элемент [поле someField] в классе сущности [класс Campaign] использует тип коллекции [класс java.util.Vector], когда спецификация JPA поддерживает только java.util.Collection, java.util.Set, java.util.List или java. .util.Map. Этот тип поддерживается с активной загрузкой; использование отложенной загрузки с этим типом коллекции требует дополнительной настройки и реализации IndirectContainer, которая расширяет [класс java.util.Vector] или устанавливает отображение для использования базовой косвенности и типа ValueholderInterface.

Два возможных решения могут исправить мое поведение:

  • используйте FetchType.EAGER (тогда я мог бы остаться с Vector)
  • используйте List (как сказано в спецификации ...)
person Hank    schedule 21.04.2010