我使用hibernate并尝试优化加载带有
注释的外部实体@ManyToOne(fetch = FetchType.LAZY)
我不想在hibernate查询期间检索外部实体并使用LAZY获取类型。 稍后(在会话已经关闭之后),我想获得该外来实体但使用与hibernate不同的工具(另一个已经存储外部实体的缓存DAO(GuavaCache))。
但是,我立即得到了一个LazyInitializationException。
我无法用@Transient替换@ManyToOne注释,因为删除@MabyToOne后,遗留的HQL代码太多了。
有人建议让getter方法最终并且不要直接访问实体字段,而只是使用getter。这是一个例子:
private int foreignId;
@Basic
@Column(name = "foregn_id")
public int getForeignId() { return foreignId;}
public void setForeignId(int id) { this.foreignId = id; }
// private DBForeignEntity foreignEntity; no more sense to have this field
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "foregn_id", referencedColumnName = "id", nullable = false, insertable = false, updatable = false)
public final DBForeignEntity getForeign() {
// return foreignEntity; deprecated usage! Hibernate will create proxy object and throw LazyInitException after session was closed
return getFromCache(getForeignId());
}
public void setForeign(DBForeignEntity foreignEntity) {
// this.foreignEntity = foreignEntity; no more sence for having setter at all
}
这个丑陋的解决方案排除了任何持久嵌套实体的能力,因为不再有外国实体的设置者了!
是否有另一种解决方案来弃用Hibernate为我的实体创建代理对象? 如果会话关闭,如何避免LazyInitializationException? 在这种情况下,非代理是否有任何不良后果?
答案 0 :(得分:0)
在当前情况下,hibernate代理只有子(foreignEntity)实体,而不代理当前(父)实体。因此,检查外部实体的实例并将其替换为自定义加载:
是没有问题的private int foreignId;
@Basic
@Column(name = "foregn_id")
public int getForeignId() { return foreignId;}
public void setForeignId(int id) { this.foreignId = id; }
private DBForeignEntity foreignEntity;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "foregn_id", referencedColumnName = "id", nullable = false, insertable = false, updatable = false)
public final DBForeignEntity getForeignEntity() {
if (foreignEntity instanceof HibernateProxy) {
foreignEntity = getFromCache(foreignId);
}
return foreignEntity;
}
public void setForeign(DBForeignEntity foreignEntity) {
this.foreignEntity = foreignEntity;
}
此外,在调用
期间没有LazyInitExceptionDBParentEntity.getForeignEntity()