Spring, @Transactional and Hibernate Lazy Loading

前端 未结 3 1883
孤独总比滥情好
孤独总比滥情好 2021-02-04 10:16

i\'m using spring + hibernate. All my HibernateDAO use directly sessionFactory.

I have application layer -> service layer -> DAO layer and all collections is lazly loade

3条回答
  •  不知归路
    2021-02-04 10:45

    Hibernate recently introduced fetch profiles which (in addition to performance tuning) is ideal for solving issues like this. It allows you to (at runtime) choose between different loading and initialization strategies.

    http://docs.jboss.org/hibernate/core/3.5/reference/en/html/performance.html#performance-fetching-profiles

    Edit (added section on how to set the fetch profile using an interceptor):

    Before you get started: Check that fetch profiles actually will work for you. I haven't used them myself and see that they are currently limited to join fetches. Before you waste time on implementing and wiring up the interceptor, try setting the fetch profile manually and see that it actually solves your problem.

    There are many ways to setup interceptors in Spring (according to preference), but the most straight-forward way would be to implement a MethodInterceptor (see http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop-api.html#aop-api-advice-around). Let it have a setter for the fetch profile you want and setter for the Hibernate Session factory:

    public class FetchProfileInterceptor implements MethodInterceptor {
    
        private SessionFactory sessionFactory;
        private String fetchProfile;
    
        ... setters ...    
    
        public Object invoke(MethodInvocation invocation) throws Throwable {
            Session s = sessionFactory.openSession(); // The transaction interceptor has already opened the session, so this returns it.
            s.enableFetchProfile(fetchProfile);
            try {
                return invocation.proceed();
            } finally {
                s.disableFetchProfile(fetchProfile);
            }
        }
    }
    

    Lastly, enable the interceptor in the Spring config. This can be done in several ways and you probably already have a AOP setup that you can add it to. See http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-schema.

    If you're new to AOP, I'd suggest trying the "old" ProxyFactory way first (http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop-api.html#aop-api-proxying-intf) because it's easier to understand how it works. Here's some sample XML to get you started:

    
      
      
    
    
    
      
      ...
    
    
    
        
        
            
                existingTransactionInterceptorBeanName
                fetchProfileInterceptor
            
        
    
    

提交回复
热议问题