簡體   English   中英

LazyInitializationException,用於int

[英]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; }
}

發生的是:

  1. 提取Parent對象
  2. parent.getMyObject()以獲取MyObject實例
  3. 實際上,此MyObject實例是一個沒有任何字段的代理。
  4. 一旦在此MyObject實例上調用方法,就會得到LazyInitializationException

提取對象時,請確保存在會話並創建了事務。 但是在獲取之后,我立即關閉了交易。

調用getMyObject()或調用getter時,我沒有創建事務。 我想這就是問題所在。 我會測試是否有作用。

編輯2:

事實證明,我確實需要在事務中調用獲取器。 但這本身還不夠。

第二個問題是在已提交的事務中獲取了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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM