【问题标题】:hibernate with ehcache not working well使用 ehcache 休眠不能正常工作
【发布时间】:2015-04-28 23:01:35
【问题描述】:

我在我的项目中使用 Spring 4、Hibernate 4。 最近,我在项目中添加了ehcache。有一个实体 com.xxx.Employee 持有另一个实体 com.xxx.User。我使用 HibernateTemplate findByCriteria(DetachedCriteria, int, int) 执行查询,然后通过 HibernateTemplate get(entityName, id) 进行另一个查询,日志中没有显示 SQL,这似乎是第二个缓存有效,但是, Employee 用户丢失,抛出“org.hibernate.LazyInitializationException: could not initialize proxy - no Session”。

是否需要添加额外设置才能将 Object 的 Object 值保存到缓存中?

<hibernate-mapping package="com.xxx">
<class name="Employee" table="t_employee">
    <cache usage="read-write" include="all"/>
    <id name="personId" column="person_id">
        <generator class="identity" />
    </id>

    <property name="name" column="name" />

    <many-to-one name="department" column="department_id" fetch="join" not-null="false" />
    <many-to-one name="user" column="user_id" fetch="join" not-null="false" cascade="all-delete-orphan" unique="true"/>

</class>

<hibernate-mapping package="com.xxx">
<class name="User" table="t_user">
    <cache usage="read-write"/>
    <id name="userId" column="user_id">
        <generator class="identity" />
    </id>
    <property name="name" column="name" not-null="true" />
    <property name="loginName" column="login_name" unique="true" not-null="true" />
    <property name="password" column="password" not-null="true"  />
    <many-to-one name="employee" column="employee_id" fetch="join" not-null="false" />
    <many-to-one name="role" class="Role" column="role_id" fetch="join" not-null="true" />
    <property name="lock" column="col_lock" type="integer" />
    <property name="createDate" column="create_date" />
    <property name="updateDate" column="update_date" />
    <property name="passwordUpdateDate" column="pwd_update_date" />
    <property name="loginTimes" column="login_times" type="integer" />
    <property name="lastLoginDate" column="last_login_date" />
    <property name="comment" column="comment" />

</class>

public T getOneById(Serializable id) throws TamsException {
    if (id == null) {
        logger.error("getOneById id is null");
        throw new TamsException("getOneById id is null");
    }
    T t;
    try {
        log.info("get " + getEntityName() + " by ID : " + id);

        HibernateTemplate ht = getHibernateTemplate();
        ht.setCacheQueries(true);
        t = (T) ht.get(getEntityName(), id);
        return t;
    } catch (Exception e) {
        throw new TamsException("get " + getEntityName() + ":  failure!", e);
    } finally {
        log.info("get " + getEntityName() + " by ID : " + id + " success!");
    }
}


public List<T> queryByCondition(QueryCondition condition)
        throws TamsException {

    log.info("query " + getEntityName() + " by: " + condition + " ...");
    try {
        int firstResult = 0;
        int maxResults = 0;

        DetachedCriteria c = DetachedCriteria
                .forEntityName(getEntityName());

        if (condition != null) {
            firstResult = condition.getFirstResult();
            maxResults = condition.getMaxResults();
            assembleCriteria(condition, c);
        }
        HibernateTemplate ht = getHibernateTemplate();
        ht.setCacheQueries(true);
        @SuppressWarnings("unchecked")
        List<T> list = (List<T>) ht.findByCriteria(c, firstResult,
                maxResults);

        log.info("query " + getEntityName() + " by: " + condition
                + " ret size --> " + list.size());
        return list;
    } catch (Exception e) {
        throw new TamsException("query " + getEntityName() + " by: "
                + condition + " failure!", e);
    }

}

【问题讨论】:

  • 最后我用Spring Cache代替了Hibernate二级缓存。

标签: spring hibernate ehcache


【解决方案1】:

您收到org.hibernate.LazyInitializationException: could not initialize proxy - no Session 错误,因为属性Employee.user 配置了选项lazy=proxy(这是默认设置,未提及时)。

这里是piece from documentation

lazy(可选 - 默认为代理):默认情况下,单点 关联被代理。 lazy="no-proxy" 指定属性 应该在第一次访问实例变量时延迟获取。 这需要构建时字节码检测。懒惰=“假” 指定将始终急切地获取关联。

所以,现在你有两个选择:

  1. 使用lazy=false 急切地获取关联
  2. 在处理所需的关联之前打开Session

【讨论】:

  • 如果我不使用缓存,代码运行良好,所以我认为问题是当 Hibernate 从缓存中获取对象时,它错过了一些东西。
猜你喜欢
  • 2013-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-12
  • 1970-01-01
  • 1970-01-01
  • 2012-12-11
  • 2011-07-13
相关资源
最近更新 更多