从ehcache加载hibernate对象时的Lazyinitialization异常

时间:2012-06-06 20:32:23

标签: hibernate caching ehcache entities lazy-initialization

我将hibernate实体存储在ehcache中。当调用facade层来检索实体时,我的拦截器将调用该方法并对其进行缓存。下次调用相同方法时,将从缓存中返回实体。一切正常。

我的实体有一些属性(对象或关联实体),它们被定义为FetchType.Lazy。它是这样的,

@JoinColumn(name = "inventory_item_oid", referencedColumnName = "inventory_item_oid")
@ManyToOne(fetch = FetchType.LAZY)
private InventoryItem inventoryItem;

因此,并非所有属性都被加载。当需要库存物品时,它被调用。此调用抛出了LazyInitialization异常。

由于我的缓存值存在一天,因此可以在它过期之前被调用任意次。

其中一个调用抛出了上述异常。

我发现使用长hibernate会话,我可以解决这个问题。但它不起作用,因为我的是基于请求/响应的应用程序。

还有一种方法我需要在访问其属性之前检查InventoryItem是否为null,如果它为null,那么我需要单独获取该值并将其附加到父级。这似乎很好......但由于我有很多实体,所以需要大量的工作。

我想知道是否有其他方法可以获取定义为懒惰的对象。

1 个答案:

答案 0 :(得分:1)

您不应自己在EHCache中缓存实体。相反,您应该将Hibernate配置为使用二级缓存,并使用EHCache作为其实现。

最终结果将是相同的:您的实体将被缓存,您将保存到数据库的往返。但是通过使用二级缓存,一切都将是透明的:您将从会话中加载实体,Hibernate将自动将它们存储在缓存中。如果你从会话中重新加载它们,Hibernate将从缓存中获取它们。如果您更新实体,它将从缓存中逐出,以确保下次重新加载新副本。

与您手工制作的解决方案的另一个巨大差异是Hibernate将返回附加的实体。因此,如果您只是调用cachedEntity.getNonCachedEntity(),Hibernate将延迟加载非缓存实体,就像您根本没有缓存一样。

实体是来自数据库还是来自二级缓存不会改变任何内容:如果属性是延迟加载的,并且如果会话关闭后访问此属性,则必须初始化lazy属性会议结束前。

致电Hibernate.initialize(foo.getInventotyItem())进行初始化。

Hibernate documentation中的更多信息。