смущен ленивой загрузкой - PullRequest
1 голос
/ 08 ноября 2011

При попытке выполнить несколько тестов на ленивую загрузку, чтобы проверить, правильно ли я понимаю, я запутался.

Вот сущности, которые я использую в моем тесте:

@Entity
public class Family {
@Id
private int id;


@OneToMany(mappedBy="family", fetch=FetchType.LAZY)
private Set<Person> members;

//getters & setters

public String toString(){
    String s="";
    for(Person p:getMembers()){
        s+=p.getFirstName();
    }
    return s;
}
}

@Entity
public class Person implements Comparable<Person>{
@Id
private int id;

private String firstName;
private String lastName;

@ManyToOne
private Family family;

//getters &setters
}

вот мой основной метод:

public static void main(String[] args) {
    factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
    em = factory.createEntityManager();

    Query q = em.createQuery("select f from Family f");
    List<Family> families= q.getResultList();

    em.clear();
    em.close();
    factory.close();

    for(Family f:families){
        System.out.println(f);
    }
}

Что я понял из отложенной загрузки, так это то, что если атрибут помечен для извлечения лениво, и к нему не обращаются, пока он управляется, он не будет загружен в память, и любая попытка получить к нему доступ позже не будет работать. Что меня смущает, так это то, что описанный выше тест не вызывает проблем при доступе к атрибуту lazy members через отдельный список Family даже после закрытия EM и EMF! ... это нормально? Неужели я не понимаю ленивую концепцию загрузки?

Примечание: Я использую среду J2SE со встроенной БД. Мой провайдер EclipseLink

Заранее спасибо
George

Ответы [ 3 ]

2 голосов
/ 08 ноября 2011

Убедитесь, что вы используете агент eclipselink или статическое плетение. Если вы не используете ни то, ни другое, LAZY не будет соткаться, и у вас будет EAGER.

EclipseLink также поддерживает доступ к отношениям LAZY после закрытия EntityManager. Хотя не после того, как фабрика закрыта. Однако, если объект был в кеше, он может работать и после закрытия. Кроме того, если у вас есть еще одна фабрика, открытая в том же модуле персистентности, тогда блок персистентности все еще открыт.

2 голосов
/ 09 ноября 2011

Убедитесь, что ваш метод toString не запущен до закрытия фабрики, например, если объект регистрируется.Я бы не рекомендовал запускать отношения в методе toString, так как это подвержено ошибкам и может быть вызвано неожиданно.Включение ведения журнала EclipseLink поможет показать вам, где к нему осуществляется доступ в течение жизненного цикла фабрики, при условии, что это не является частью проблемы.

0 голосов
/ 08 ноября 2011

Это может быть потому, что провайдеру JPA не требуется использовать отложенную инициализацию. Это не обязательное требование для поставщика JPA, но a подсказка .

JPA требуется для быстрого извлечения данных, когда указано FetchType.EAGER, но не требуется для отложенного извлечения данных, когда указано FetchType.LAZY.

...