任何人都可以幫我解決一個我認爲簡單的JPA問題。我試圖在我的JPA持久性框架中編寫通用的惰性負載管理器,因此應用程序堆棧中較高的層可以訪問延遲加載的數據,而無需處理具體細節。重新連接實體以延遲加載集合(JPA /休眠)
我有一個延遲加載經理:
public class JpaLazyLoader extends AbstractJpaDAO<Void> implements LazyLoader
{
public JpaLazyLoader()
{
super(void.class);
}
@Transactional(readOnly=true)
public <T,E> T get(ILazyGetter<T,E> p_getter) throws Exception {
// reattach the object to the session
E l_entity = getEntityManager().merge(p_getter.getEntity());
// return the getter data
return p_getter.get(l_entity);
}
}
懶吸氣是這樣的:
public interface ILazyGetter<T,E> extends Serializable
{
public E getEntity();
public T get(E p_entity) throws Exception;
}
這個想法是,它會像這樣使用:
return m_lazyLoader.get(new ILazyGetter<Collection<Child>, Parent>() {
private static final long serialVersionUID = 1L;
public Parent getEntity() {
return getValue(); // get the parent object from somewhere
}
public Collection<Child> get(Parent p_entity) throws Exception {
// children are a lazy-loaded Set<Child>
return p_entity.getChildren();
}
});
Parent中的註釋是這樣的:
@Entity(name="parent")
public class Parent implements Serializable {
private static final long serialVersionUID = 1L;
....
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.AUTO)
protected Long id;
@OneToMany
@JoinTable
(
name="parent_child_associations",
joinColumns={ @JoinColumn(name="parent_id", referencedColumnName="id") },
inverseJoinColumns={ @JoinColumn(name="child_id", referencedColumnName="id", unique=true) }
)
protected Set<Child> children;
}
父對象裝載在不同的事務,然後分離。我希望將父母重新連接到另一個會話(在@transactional位內)是件微不足道的事,但我無法讓它工作。我已經嘗試過樂觀/悲觀/合併之前和之後沒有鎖定,但似乎沒有工作。
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: test.Parent.children, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:566)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:186)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:545)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:124)
at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:180)
這是錯誤的方式去做事嗎?如果是這樣,那麼「正確」的方式是什麼?如果不是,我做錯了什麼?
感謝所有幫助
顯然,你做成功獲取集合,但它初始化?似乎你退還未打開的包,當你嘗試迭代那個包時,它會嘗試打開它,給你例外。 當您迭代集合時是否有打開的會話?如果是這樣,你可以嘗試調用Hibernate.initialize()? –
是的,這正是我出錯的地方。 - 我不想將我的JPA綁定到Hibernate,所以我確保集合被初始化。見下面的評論。 – fancyplants