2014-09-02 3 views
2

Я работаю с JPA 2.1 (EclipseLink 2.5.1) и JBoss 7.1.@ManyToOne (fetch = FetchType.LAZY) lazy loading not working

Я определить очень простые объекты JPA:

@Entity 
@Table(name="APLICACIONES_TB") 
public class Aplicacion implements Serializable { 

    @Id 
    @Column(name="COD_APLICACION_V") 
    private long codAplicacionV; 

    @Column(name="APLICACION_V") 
    private String aplicacionV; 

    @OneToMany(mappedBy="aplicacion") 
    private Collection<Prestacion> prestaciones; 

    ... getters and setters 
} 

@Entity 
@Table(name="PRESTACIONES_TB") 
public class Prestacion implements Serializable { 

    @Id 
    @Column(name="COD_PRESTACIONES_V") 
    private String codPrestacionesV; 

    @Column(name="DESCRIPCION_V") 
    private String descripcionV; 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name = "COD_APLICACION_V")  
    private Aplicacion aplicacion; 

    ... getters and setters ... 
} 

Я разработал staless EJB, который выполняет запрос, чтобы получить некоторые «Aplicacion» сущности.

@Stateless 
@LocalBean 
public class DocuEJB implements DocuEJBLocal 
{ 
    @PersistenceContext(name="DocuEjb", type=PersistenceContextType.TRANSACTION) 
    private EntityManager em; 

    public Prestacion getResult(String name) 
    { 
    return em.createNamedQuery("ExampleQueryName", Prestacion.class).getSingleResult(); 
    } 
} 

Поскольку я работаю с JSF 2.1 EJB впрыскивается в управляемом компоненте:

@ManagedBean(name = "ManagedBean") 
@RequestScoped 
public class ManagedBean 
{ 
    @EJB DocuEJB docuEjb; 

    public String doSomething() 
    { 
    Prestacion entity = docuEjb.getResult("egesr"); 

    if (entity != null) 
    { 
     // It should return null because 'entity' should be detached 
     Aplicacion app = entity.getAplicacion(); 

     // but 'app' entity is not null, ¿why not? 
     System.out.println (app.getCodAplicacionV()); 
    } 
    } 
} 

Ленивая загрузка не работает даже тогда, когда ленивая загрузка была определена для поля на «aplicacion» Объект Prestacion. Код размещен прежде, чем должен возвращать NullPointerException в следующей строке:

System.out.println (app.getCodAplicacionV()); 

, потому что «приложение» объект отсоединяется и ленивая загрузка была настроена.

Почему не работает ленивая загрузка?

Благодаря

+2

Попробуйте добавить @Transactional on doSomething() – Xstian

+2

Если getAplicacion() вызывается в отдельном объекте, он должен поднять печально известное исключение LazyInitializationException. Это не ... так приложение все еще прилагается. –

+0

@Xstian - Я пробовал то, что вы предлагали (контекст постоянства транзакций), но у меня тот же результат. – Eduardo

ответ

0

Попробуйте добавить @Transactional на DoSomething(), я думаю, что менеджер транзакций не очень хорошо настроен.

here официальная весенняя документация. В любом случае, можете ли вы добавить свои конфигурации пружин, чтобы мы могли лучше вам помочь. :)

+0

Когда вы говорите @ Transactional, вы имеете в виду аннотацию @TransactionAttribute (TransactionAttributeType.NOT_SUPPORTED)? doSomething - это метод EJB – Eduardo

+0

Моя мысль заключается в том, что транзакция закрыта, когда вы пытаетесь получить отношения. Я предлагаю вам поведение, подобное SpringTransaction. – Xstian

0

Я не думаю, что поведение вашей встречи ненормальный или ваш вопрос должен указать это явно:

  • EJB, по умолчанию транзакционной
  • Ваш JSF впрыснуть в EJB, с @EJB, и я предположим, JBoss может создать ссылку на java, а не прокси
  • Сущность управляется, потому что транзакция не завершена, она завершится, когда заканчивается doSomething.

Ваша сущность затем загружается в EntityManager, а ленивые загрузки - потому что есть контекст.

Вы бы назвали em.evict(entity) с результатом, который вы получаете, это, вероятно, потерпит неудачу, потому что сущность не будет управляться больше.

+0

Я согласен с тобой. Но если вы посмотрите на код, который я опубликовал, ленивая ссылка решается после завершения метода doSomething. И по этой причине он не должен разрешать ленивую ссылку. – Eduardo

+0

Например, где он ленивый загружен, где он не должен? (потому что ваш пример указывает на 'doSomething', а не на то место, где вы его используете). , – NoDataFound

+0

Извините, вы правы, я объяснил это плохо. Метод getResult является методом EJB, и поскольку тип контекста персистентности, определенный для EJB, является транзакцией, объект, возвращаемый методом getResult, должен быть отсоединен. С другой стороны, метод doSomething является управляемым компонентом, и я думаю, что контейнер JEE не управляет транзакциями для управляемых bean-методов. – Eduardo

Смежные вопросы