Eclipselink Ленивая Загрузка - PullRequest
2 голосов
/ 13 декабря 2011

Я запускаю тест на eclipselink JPA 2, чтобы определить, как работает отложенная загрузка коллекции. Я предположил, что если вы загружаете сущность, то в первую очередь загружаются все нетерпеливые элементы, затем в сеансе JPA загружаются ленивые элементы, когда вы их запрашиваете или касаетесь их (обращайтесь к ним каким-либо образом, как получить размер ленивой коллекции). Проблема у меня заключается в следующем: когда я отсоединяю сущность от сеанса, отложенная коллекция загружается и становится доступной, даже если я ее не просил ?? Я либо неправильно понимаю JSR, либо это нормальное поведение в eclipselink. От использования hibernate я знаю, что это не происходит.

EntityManager em = emf.createEntityManager();
        AloadTest at1 = em.find(AloadTest.class, pkLazy);

        serializeObject(at1,"InSessionLazy");

        em.detach(at1);
        em.close();

Если я запускаю это в отладке и наблюдаю за своими ленивыми элементами, я вижу, что они не загружаются, когда я получаю доступ к моему объекту 'at1', но в ту минуту, когда я перехожу через строку em.detach (at1), ленивый объекты загружены.

У меня есть определенная ленивая коллекция в моем AloadTest C.D. как таковой: ...

@OneToMany(fetch = javax.persistence.FetchType.LAZY, cascade = CascadeType.PERSIST, /*, cascade = CascadeType.ALL, */mappedBy = "aloadtest")
    public Set<CloadLazyMultitest> getCloadLazyMultitest() {
        return cloadLazyMultitest;
    }
    public void setCloadLazyMultitest(Set<CloadLazyMultitest> cloadLazyMultitest) {
        this.cloadLazyMultitest = cloadLazyMultitest;
    }

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

РЕДАКТИРОВАТЬ: Я сделал ваш тест Джеймс, и вы правы насчет теста косвенности:

logger.info(" ARE WE LAZY LOADED BEFORE :"+((IndirectSet)at1.getCloadLazyMultitest()).isInstantiated()); 

        em.detach(at1);

        logger.info(" ARE WE LAZY LOADED AFTER :"+((IndirectSet)at1.getCloadLazyMultitest()).isInstantiated()); 

И вывод на мой логгер:

17:14:16.707 [main] INFO  c.c.t.j.t.JpaI3EagerAndLazyLoadingTest -  ARE WE LAZY LOADED BEFORE :false

17: 14: 16.723 [main] INFO c.c.t.j.t.JpaI3EagerAndLazyLoadingTest - НАМ ЛЕНЫ ЗАГРУЖАЕТСЯ ПОСЛЕ истины: true

Моя точка зрения? почему я загружаю ленивые коллекции, я не спрашиваю о коллекции, только родительский объект. Что бы произошло, если бы у меня была цепочка из 2 или 10 коллекций, каждая из которых помечена как ленивая коллекция? Я думаю, что это будет довольно накладные расходы. Это никогда не было проблемой с Hibernate, но так как eclipselink теперь является ссылкой JPA, я должен создать решение, основанное на этом.

Конечно, можно отсоединить объект, сделать его «грязным», выполнить некоторую обработку и повторно присоединить к новому сеансу. Я больше думаю в среде «длинного разговора», возможно, сессионных компонентов без состояния и веб-интерфейса?

Ответы [ 2 ]

2 голосов
/ 13 декабря 2011

EclipseLink позволяет загружать ленивые отношения, пока соединение все еще доступно, как описано здесь: http://forums.oracle.com/forums/thread.jspa?messageID=1706796

2 голосов
/ 13 декабря 2011

Если посмотреть на последний код EclipseLink, не похоже, что detach () запустит отложенную коллекцию. Вы должны отсоединить его?

В общем случае EclipseLink позволяет вам получить доступ к отношениям LAZY после закрытия EntityManger, поэтому, даже если вы отсоединили объект, он все равно будет иметь доступ к отношениям (если вы его не сериализуете).

Вы можете проверить, созданы ли отношения, используя,

((IndirectSet)at1.getCloadLazyMultitest()).isInstantiated()

Проверьте это до и после вызова detach ().

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

...