Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java LazyInitializationException,用于int_Java_Hibernate_H2_Lazy Initialization_Proxy Classes - Fatal编程技术网

Java LazyInitializationException,用于int

Java LazyInitializationException,用于int,java,hibernate,h2,lazy-initialization,proxy-classes,Java,Hibernate,H2,Lazy Initialization,Proxy Classes,具有整数字段的简单类: @Entity @Cacheable @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) @Table(name = "myObject") public class MyObject { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id

具有整数字段的简单类:

@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; }
}
使用简单的实用程序方法从数据库中提取对象:

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>
发生的情况是:

  • 获取父对象
  • 调用
    parent.getMyObject()
    以获取
    MyObject
    实例
  • 这个
    MyObject
    实例实际上是一个没有任何字段的代理
  • 只要我在这个
    MyObject
    实例上调用一个方法,我就会得到
    LazyInitializationException
  • 当我获取我的对象时,我确保会话存在并且创建了事务。但在抓取之后,我立即关闭了交易

    调用
    getMyObject()
    或调用getter时,我没有创建事务。我想这就是问题所在。我将测试这是否有区别

    编辑2: 事实证明,我确实需要在事务中调用getter。但这本身还不够

    第二个问题是在已提交的事务中获取父对象。因此,代理对象不再绑定到事件。我猜这就是他们所谓的“分离物体”。(哈哈,我只是边走边学。)

    我必须通过调用
    会话#更新(代理)
    方法来“重新连接”这个对象。现在我终于可以毫无例外地调用getter了。

    // 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()?

    在sql级别,refCount是一个索引?代码中的
    标准是什么?尝试调用
    getRefCount
    而不是
    初始化
    @ShadowRay hibernate为此字段创建了一个索引,这是正确的。这实际上是一个大数据数据库。大约有100万个MyObect对象。每个
    MyObject
    都有多个
    Parent
    对象。实际上,有多个引用计数器(例如,
    refCount
    ),用于计算它们拥有多少个具有特定属性的父级。整个想法是为
    MyObject
    (即包含预先计算的数据)创建一个平面记录,这将使以后更容易计算复杂的统计数据。>>但我从这个问题中学到的是,我可能>>以错误的方式使用事务。我想我应该进行更长的>>事务,这些事务包含回迁和对getter的调用正确的?不,通常您可以调用分离对象的getter和setter(不过,对于非延迟加载的字段)。但在您的情况下,由于某种原因,所有文件都是延迟加载的,您无法这样做。请尝试使用此注释参数:@org.hibernate.annotations.Cache(include=“non-lazy”,use=cacheconcurrencysttrategy.READ\u-WRITE);不懒惰的人,没有帮助。你发完后我马上就试了。但与此同时,我做了一次重新测试,发现我不得不调用
    会话#update(myObject)
    // 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();