2017-02-19 10 views
2

У меня плохое понимание ленивой выборки, так как я не работаю, поскольку я читаю об этом в книге, говорят, что в ленивом наборе jpa загрузит объекты только тогда, когда они будут доступны через geters, поэтому я создал проект Arquillian для тестирования этой концепции, но это не сработает. вот мои две сущностиПочему Lazy Fetch не работает JPA

Person

package com.actionbazaar.model; 

@Entity 
@TableGenerator(
     initialValue = 5, 
     name = "PERSON_SEQ", 
     table = "PERSON_SEQ_TABLE", 
     pkColumnName = "SEQ_NAME", 
     pkColumnValue = "PERSON", 
     valueColumnName = "SEQ_VALUE") 
public class Person implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id; 

    private String fname; 
    private String lname; 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "owner", cascade = CascadeType.PERSIST) 
    List<Address> addresses; 
    //getters and setters 
} 

Адрес

@Entity 
public class Address implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id; 
    private String city; 
    private String zip; 
    private String street; 

    @ManyToOne 
    private Person owner; 
//getters and setters 
} 

У меня есть сессионный компонент с помощью этого метода

public Person getFirstPerson() { 
    Person p = em.find(Person.class, 1); 
    em.detach(p); 
    //why this call does not create an exception 
    p.getAddresses().get(0); 
    return p; 
} 

, так как я отсоединил объект до доступа к адресу, список адресов должен быть пустым, и когда я отключу его, чтобы он больше не управлялся сущ., Поэтому я не должен получать адреса для лица , проблема в том, что я могу получить адреса этого человека, даже у меня есть ленивый выбор для поля адресов и отсоединение объекта до доступа в поле адресов !!!! пожалуйста некоторые есть информация.

Другое испытание

Person p= myStatlessSessionBean.getFirstPerson(); 
myOtherStalessSesionBean.moveAllPeopleToCity("NY"); 
if(p.getAddresses().get(0).getCity().equals("NY")) 
{ 
    system.out.prinln("person moved"); 
} 
else { 
system.out.prinln("person did not move"); 
} //prompts person did not move 

ответ

4

Да, приятель, вы были правы. Вы здесь не делаете ничего плохого. Я только что открыл Pro JPA 2, второе издание книги и нашел это:

here is the snapshot

Вы используете GlassFish встраиваемый, которая на самом деле причиной проблемы. У вашего кода нет проблем. Как уже упоминалось автором вышеупомянутой книги,

Некоторые поставщики могли бы попытка решить отношения, в то время как другие могут просто выбросить исключение или оставить атрибут UNINITIALIZED.

Итак, в вашем случае отношения разрешены, а не ленивая загрузка. Просто выполните тот же пример с использованием другого поставщика, и вы не столкнетесь с какой-либо проблемой. Здесь, используя встроенную стеклянную панель, lazyfetch не работает. В противном случае исключение должно быть выбрано, поскольку переменная p отсоединена.

Вот link, где я также прочитал эту прекрасную часть информации

Вот снимок сверху ссылку snapshot

+0

yup .. Вы правы. Мне было любопытно узнать, почему это произошло. Дополнительная информация получена. Спасибо @achabahe –

+1

@achabahe Я подозревал, что это была причина, но вы отметили свой вопрос «спящим», хотя, похоже, вы его не используете. Это вводит в заблуждение. –

+0

Возможно, он пытался добраться до спящего, зная людей: D? @JBNizet^_^ –

1

Вы только отсоединение родительского объекта, Person. Вы не отделяете дочерние объекты, адреса, а когда получаете адреса, это относится к объектам, которые все еще управляются контекстом персистентности.

Если вы хотите, чтобы дети были также отсоединены, вы должны использовать CascadeType.DETACH.

Можно сказать: «Но у меня FetchType установлен LAZY!». Просто потому, что он LAZY, не означает, что объект имеет значение null. Hibernate возвращает объекты прокси для типов коллекций, и как только вы попытаетесь получить к ним доступ, он заполнит их значения.

+0

как о втором тесте!, Я изменил каскад добавить CascadeType.DETACH, но все равно такая же проблема, сначала я хочу знать, правильно ли понятна концепция и поведение, которое я ожидаю, это правильный – achabahe

+1

Я согласен с @Tahir. По спецификации JPA: «Когда требуется взаимодействие между поставщиками, приложение не должно использовать ленивую загрузку». JPA Spec также упоминает, что LAZY fetch - это просто подсказка, и это говорит мне, что ее реализация предоставляется поставщику. – raminr

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