В настоящее время я перемещаю (работающее) приложение из EclipseLink в Hibernate JPA, в основном все прошло довольно гладко, но я нахожу одну вещь, которую не могу объяснить, а также не могу придумать ни одного хорошего поиска. термины!
По сути, у меня есть четыре сущности с отношениями один-ко-многим, образующими цепочку:
EntityA имеет список EntityB, каждый из которых имеет список EntityC, каждый из которых имеет список EntityD
тогда каждый из них имеет отношение многие-к-одному, идущее в другую сторону, поэтому:
EntityD имеет EntityC, который имеет EntityB, который имеет EntityA.
То есть (сильно уменьшено для ясности):
@Entity
public class EntityA {
@OneToMany (cascade = CascadeType.All, mappedBy = "entityA")
private List<EntityB> entityBList;
...
}
@Entity
public class EntityB {
@OneToMany (cascade = CascadeType.All, mappedBy = "entityB")
private List<EntityC> entityCList;
@JoinColumn (name = "ENTITY_A", referencedColumnName = "ENTITY_A_ID")
@ManyToOne (cascade = CascadeType.PERSIST, optional = false)
private EntityA entityA;
}
@Entity
public class EntityC {
@OneToMany (cascade = CascadeType.ALL, mappedBy = "entityC")
private List<EntityD> entityDList;
@JoinColumn (name = "ENTITY_B", referencedColumnName = "ENTITY_B_ID")
@ManyToOne (cascade = CascadeType.PERSIST, optional = false)
private EntityB entityB;
}
@Entity
public class EntityD {
@JoinColumn (name = "ENTITY_C", referencedColumnName = "ENTITY_C_ID")
@ManyToOne (cascade = CascadeType.PERSIST, optional = false)
private EntityC entityC;
}
Я получаю EntityA из базы данных (просматривая его по первичному ключу), и, таким образом, получаю хорошо заполненный экземпляр EntityA с PersistentBag для моего List<EntityB>
. Я вижу ленивую загрузку, возникающую при разыменовании этого List<EntityB>
, и то же самое повторяется для получения EntityC от EntityB.
На данный момент все, как я и ожидал, у меня есть EntityA, B и C, все они полностью заполнены значениями из базы данных, но затем я пытаюсь получить свой EntityD из EntityC, и обнаружил, что он нулевой.
Мой менеджер сущностей все еще открыт и активен на этом этапе, и даже если я смотрю на него в отладчике сразу после получения EntityA, я могу пройти через отношения, вплоть до EntityC, и снова увидеть «entityDList» как ноль.
Единственное решение, которое я нашел до сих пор, это использовать:
EntityManager.refresh(entityC);
, который заполняет все его элементы, включая лениво загруженный PersistentBag для entityDList.
Итак, я предполагаю, что Hibernate заполняет ссылки только на 2 уровня глубиной (или 3, в зависимости от того, как вы рассчитываете) и сдается после этого, хотя я не очень понимаю, почему это будет. Это имеет смысл для кого-либо?
Есть ли какое-либо решение, кроме .refresh? Какое-то значение конфигурации или аннотации, которое заставит Hibernate заполнить ссылки до конца?