0

我正在尝试更新我的项目的库(从 Hibernate 3.2.1 GA 到 Hibernate 4.2.8)

这个(复杂的)应用程序使用延迟加载,并且仅在我们需要时才获取对象。--> 现在似乎工作方式不同了,因为我得到了一些org.hibernate.LazyInitializationException : could not initialize proxy - no Session

@Entity
@Table(name = "CLIENTS")
public class Clients  {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "INFOIDT", insertable = true, updatable = false)
private Information info;
//...
}

当我需要在使用前了解更多关于产品的信息时:

cli.getInfo();

请注意,在我的 persistence.xml 中,我还将属性 hibernate.cache.provider_class 设置为 org.hibernate.cache.EhCacheProvider 用于二级缓存。

问题:使用 Hibernate4 迁移现有代码的简单方法是什么?(上面给出的类是一个假的例子来说明许多使用 LAZY 加载的情况)谢谢。

根据要求,请参阅下面的我的 DAO:

public class MyAppJpaDAO extends GenericJpaDAO implements IMyAppDAO {
    protected static Log log = LogFactory.getLog(MyAppJpaDAO.class);

    // Entity Manager of the project
    @PersistenceContext(unitName = "MyApp.hibernate")
    private EntityManager em;

    public News readLastNews() {
        StringBuffer sql = new StringBuffer("");
        sql.append(" select object(n) ");
        sql.append(" from News n ");
        sql.append(" Where n.flagLastStatus = 'V' ");
        sql.append(" order by n.pk.date desc ");
        Query aQuery = em.createQuery(sql.toString());

        List<News> res = (List<News>) aQuery.getResultList();
        if (res != null && res.size() != 0) {
            return res.get(0);
        }
        return null;
    }

    //...

    }

/////////////

public class GenericJpaDAO implements IGenericDAO {

    protected static Log log = LogFactory.getLog(GenericJpaDAO.class);

    @PersistenceContext(unitName = "MyApp.hibernate")
    EntityManager em;

    public Object getReference(Class _class, Object _object) {
        return em.getReference(_class, _object);
    }

    public void createObject(Object object) {
        try {
            em.persist(object);
        } catch (LazyInitializationException lie) {
            em.merge(em.merge(object));
        }
    }

    public void deleteObject(Object object) {
        try {
            em.remove(object);
        } catch (Exception e) {
            em.remove(em.merge(object));
        }
    }

    public void updateObject(Object object) {
        em.merge(em.merge(object));
    }

    //...

    }
4

3 回答 3

0

如果要使用 LazyLoading,则需要在调用 .getInfo() 时打开并连接会话。如果您尝试获取实体但会话断开或关闭,则会发生 org.hibernate.LazyInitializationException。我认为您在会话处理方面存在问题。与实体无关。

于 2014-02-06T14:55:07.760 回答
0

如果 SessionFactory 是在 Spring 上下文文件中配置的,我们可以使用 OpenSessionInViewFilter 来保持会话打开。

<filter>
    <filter-name>Hibernate Session In View Filter</filter-name>
       <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>Hibernate Session In View Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

不幸的是,我的应用程序没有这样配置......

于 2014-02-14T13:34:02.037 回答
0

有趣......但仍然没有帮助 http://www.javacodegeeks.com/2012/07/four-solutions-to-lazyinitializationexc_05.html

但我发现了一些东西:

1)Hibernate 3.2.1 GA 和 Spring 2.0 我曾经把一个有 LAZY 包的人放在一个组中,当我想从组中任何人的包中取出一些铅笔时,我能够得到它。

2)休眠 4.2.8 和 Spring 3.2.5。 如果我在获取 Person 之后并在将其放入组之前没有明确要求知道包的内容,我将有惰性异常。

如果有人可以解释我为什么...

于 2014-02-18T15:24:57.497 回答