[英]LazyInitializationException, for an int
一個帶有整數字段的簡單類:
@Entity
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@Table(name = "myObject")
public class MyObject
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(columnDefinition = "int default 0")
@Index(name = "refCount")
private int refCount;
public int getRefCount(){ return refCount; }
}
使用簡單的Utility方法從數據庫中獲取對象:
Session session = SessionFactoryUtil.getCurrentSession();
Transaction tx = session.beginTransaction();
criteria.setFetchSize(1);
T object = (T) criteria.uniqueResult();
// I tried to add this line, but it made no difference
Hibernate.initialize(object);
tx.commit();
return object;
問題如下:在獲取此對象后不久,我正在調用getRefCount
方法。 那時我遇到以下異常:
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:164)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
at mypackage.MyObject_$$_javassist_1.getRefCount(MyObject_$$_javassist_1.java)
我的hibernate配置文件(即hibernate.cfg.xml
)包含以下屬性:
<property name="hibernate.current_session_context_class">thread</property>
我不明白的是:如果這會發生在集合中,那么我只會添加fetch = FetchType.LAZY
批注。 但是,這個簡單的int
字段不是聯接。 為什么將int
首先包裝在Proxy
中?
我試圖添加Hibernate.initialize(object);
線,但沒有任何區別。
我還嘗試了hibernate.current_session_context_class="managed"
設置。 之后,我必須手動啟動和停止所有會話。 我在每次獲取時都將其打開,並在finally塊中將其關閉。 但這也沒有區別。
這是我的第一個Hibernate項目之一。 我開始懷疑在休眠對象上調用getter之前是否應該打開事務。
我沒有使用Spring,只是使用了Hibernate。
實際上有一個父對象(我最初認為這並不重要)。 此Parent
對象包含指向MyObject
的鏈接
@Entity
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@Table(name = "parentObject")
public class ParentObject
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
// link
@ManyToOne(optional = false, fetch = FetchType.LAZY)
@ElementCollection(targetClass = MyObject.class)
@JoinColumn(name = "myObjectId")
private MyObject myObject;
public MyObject getMyObject(){ return myObject; }
}
發生的是:
Parent
對象 parent.getMyObject()
以獲取MyObject
實例 MyObject
實例是一個沒有任何字段的代理。 MyObject
實例上調用方法,就會得到LazyInitializationException
提取對象時,請確保存在會話並創建了事務。 但是在獲取之后,我立即關閉了交易。
調用getMyObject()
或調用getter時,我沒有創建事務。 我想這就是問題所在。 我會測試是否有作用。
事實證明,我確實需要在事務中調用獲取器。 但這本身還不夠。
第二個問題是在已提交的事務中獲取了Parent
對象。 結果,代理對象不再綁定到事件。 我猜這就是他們所說的“分離對象”。 (大聲笑,我只是在學習,因為我們去這里。)
我必須通過調用Session#update(proxy)
方法來“重新附加”該對象。 現在終於可以無例外地調用吸氣劑了。
// uses a transaction internally
Parent parent = MyHibernateUtil.fetch(Parent.class, ...);
MyObject object = parent.getMyObject();
...
// create a new transaction
Session session = SessionFactoryUtil.getCurrentSession();
Transaction tx = session.beginTransaction();
// reattach the object
SessionFactory.getCurrentSession().update(myObject);
int count = myObject.getRefCount();
tx.commit();
但是我從這個問題中學到的是,我可能以錯誤的方式使用了事務。 我想我應該進行更長的事務,同時包含獲取和對getter的調用。 對 ?
在關閉事務之前,嘗試調用getId函數。 不知道會發生什么,只是一個建議。
我想整個對象(在您的情況下為MyObject)被代理。 您可以調用getId而不是getRefCount()嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.