【发布时间】: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二级缓存。