I was frustrated with the way that Hibernate handles lazy initialization, because there are certain cases, especially in a Swing application, where it is very difficult to efficiently preload all the data, and where unacceptable architecture modifications are required to ensure that all objects which might be lazy loaded are in an open, connected session.
To fix this, I've created what I think is a very small, non-disruptive patch to allow lazy loading outside of an open, connected session.
Steps 1 through 3 add pluggable collection loading to Hibernate, but do not actually change the way that Hibernate currently functions. Steps 4 and 5 are optional steps that takes advantage of this pluggable loading behavior to implement lazy loading with closed or disconnected sessions.
Step 1:
Modify the AbstractPersistenceCollection class. This is the only change to existing Hibernate code. Overwrite the initialize(boolean) method with the following code:
protected final void initialize(boolean writing) {
if (!initialized) {
ProxyInitializer.sharedInstance().initializeCollection( this, initializing, session, getCollectionSnapshot() );
}
}
Step 2:
Create two new subclasses of LazyInitializationException:
public class SessionDisconnectedException extends LazyInitializationException {
public SessionDisconnectedException(String msg) {
super(msg);
}
}
public class SessionMissingException extends LazyInitializationException {
public SessionMissingException(String msg) {
super(msg);
}
}
Step 3:
Create a new class, org.hibernate.ProxyInitializer:
public class ProxyInitializer {
private static ProxyInitializer sharedInstance;
public static ProxyInitializer sharedInstance() {
if( sharedInstance == null ) {
sharedInstance = new ProxyInitializer();
}
return sharedInstance;
}
public static void setSharedInstance( ProxyInitializer initializer ) {
sharedInstance = initializer;
}
public void initializeCollection(PersistentCollection collection, boolean initializing, SessionImplementor session, CollectionSnapshot snapshot) throws SessionMissingException, SessionDisconnectedException {
if (initializing) {
throw new LazyInitializationException("illegal access to loading collection");
}
if( session == null ) throwSessionMissingException("no session", snapshot);
if( ! session.isOpen() ) throwSessionMissingException("session was closed", snapshot);
if( ! session.isConnected() ) throwSessionDisconnectedException("session is disconnected", snapshot);
session.initializeCollection( collection, false );
}
private void throwSessionMissingException(String msg, CollectionSnapshot snapshot) {
String name = snapshot==null ? "" : " of role: " + snapshot.getRole();
throw new SessionMissingException("failed to lazily initialize a collection" + name + " - " + msg);
}
private void throwSessionDisconnectedException(String msg, CollectionSnapshot snapshot) {
String name = snapshot==null ? "" : " of role: " + snapshot.getRole();
throw new SessionDisconnectedException("failed to lazily initialize a collection" + name + " - " + msg);
}
}
Step 4:
If you do nothing at this point, then Hibernate will continue to work exactly as it previously did. However, you may choose to subclass ProxyInitializer and override the initializeCollection() method. You can call the super method, catch the exception, and then take some other action if you wish. For example, here is how I've implemented my lazy loading. Feel free to use this verbatim, or come up with your own implementation:
private class MyLazyLoader extends ProxyInitializer {
public void initializeCollection(PersistentCollection collection, boolean initializing, SessionImplementor session, CollectionSnapshot snapshot) {
try {
super.initializeCollection(collection, initializing, session, snapshot);
} catch( SessionDisconnectedException e) {
session.reconnect();
try {
fetchInOpenSession(session, collection, initializing, snapshot);
} finally {
session.disconnect();
}
} catch(SessionMissingException e) {
SessionImplementor lazySession = (SessionImplementor)mySessionFactory.openSession();
try {
fetchInOpenSession(lazySession, collection, initializing, snapshot);
} finally {
lazySession.close();
}
}
}
private void fetchInOpenSession(SessionImplementor lazySession, PersistentCollection collection, boolean initializing, CollectionSnapshot snapshot) {
Transaction tx = null;
try {
tx = lazySession.beginTransaction();
lazySession.lock( collection.getOwner(), LockMode.NONE );
super.initializeCollection( collection, initializing, lazySession, snapshot );
tx.commit();
} catch(HibernateException e1) {
if( tx != null ) tx.rollback();
throw e1;
}
}
}
Step 5:
If you create your own subclass as in step 4, you need to set it as the shared static instance in ProxyInitializer, like this:
ProxyInitializer.setSharedInstance( new MyLazyLoader() );
That should be it... please let me know how well this works for you. I've tested this and it seems to work fine, but I have not used it in a complex application yet. I'd love to know what you think of this
分享到:
相关推荐
这就是Hibernate懒加载(Lazy Load)机制的作用所在。懒加载是一种延迟加载策略,只在真正需要时才加载关联的数据,以减少内存消耗和提高响应速度。 Gilead,全称为Hibernate for Flex,是用于Flex和Hibernate之间...
In this article I want to discuss the lazy loading mechanism provided by NHibernate. It is recommended for maximum flexibility to define all relations in your domain as lazy loadable. This is the ...
在网页开发中,"页面实现Lazy Loading效果"是一种优化用户体验的技术策略,特别是在处理大量图片或者内容的页面时。Lazy Loading,即延迟加载或惰性加载,是指只在用户滚动到可视区域时才加载图片或其他资源,而不是...
当应用需要加载图片时,特别是网络图片,采用“懒加载”(Lazy Loading)策略是提高性能和节省资源的有效方式。这个“IOS TableView Lazy Loading Demo”就是演示了如何将UITableView与懒加载技术相结合,以优化用户...
Lazy Loading:懒加载的常见问题与解决方案.docx
**标题**: Hibernate懒加载(Lazy Loading) 在Java的持久化框架Hibernate中,懒加载(Lazy Loading)是一种重要的优化策略,它的核心思想是“延迟加载”或“按需加载”。默认情况下,当一个实体被加载时,并不会...
标题中的“Hibernate lazy加载FOR Connection”指的是Hibernate框架中的一种特性,即懒加载(Lazy Loading)。在Hibernate中,懒加载是一种优化策略,它推迟对关联对象的加载,直到真正需要使用这些对象时才进行加载...
在探讨Hibernate框架中的`lazy`属性时,我们深入解析了其功能、应用场景以及与之相关的潜在问题,尤其关注于如何有效利用此特性以优化数据库性能和应用响应速度。 ### Hibernate框架简介 Hibernate是一个开放源码...
在移动设备上,由于网络资源有限以及用户对页面加载速度的高要求,图片懒惰加载(Lazy Loading)技术成为了一种优化网页性能的有效方法。"lazyloading.rar"这个压缩包文件提供了一个实现移动端图片懒惰加载的解决...
Lazy Loading:CSS懒加载策略.docx
Lazy Loading:懒加载技术概论.docx
Lazy Loading:JavaScript懒加载实现.docx
DWR 是一种让 JavaScript 在浏览器中直接调用服务器端 Java 方法的技术,而 Hibernate 是一个流行的Java持久化框架,它支持对象关系映射(ORM)以及延迟加载(Lazy Loading)功能。 在描述中提到的问题是,当使用...
Lazy Loading:懒加载与用户体验.docx
Lazy Loading:视频懒加载实现方法.docx
Lazy Loading:懒加载与SEO优化.docx
Lazy Loading:懒加载与性能优化.docx
在提供的"lazyLoading.rar"压缩包中,包含了一个完整的实现图片懒加载的实例。其中,HTML5页面应该包含了使用`data-src`的`<img>`标签,JavaScript文件(可能是.js后缀)则包含了处理滚动事件和图片加载逻辑的代码。...
0023_极智AI_解读算法部署中需要注意的LazyLoading-个人笔记
Lazy Loading:懒加载框架与库介绍.docx