Hi, I know that this has been discussed lot of times. I just can't understand how this work or where my mistake is.
I think giving you a reduced example is the best way to show you what I'm trying to do and what assumptions I'm taking...
I have a Product class with a name. The name is a String property that is lazy.
My DAO:
public abstract class HibernateProductDAO extends HibernateDaoSupport implements ProductDAO
{
public List getAll()
{
return this.getHibernateTemplate().find("from " + this.getDomainClass().getSimpleName());
}
}
My Service Interface:
public interface ProductService {
//This methods are Transactional, but same exception error is thrown if there weren't
@Transactional
public Product getProduct();
@Transactional
public String getName(Product tp);
}
My Service Implementation:
public class ProductServiceImpl implements ProductService {
private ProductDAO productDAO;
public Product getProduct() {
List ps = this.productDAO.getAll();
return (Product) ps.get(0);
}
public String getName(Product p){
return p.getName();
}
}
My Main class:
public class Main {
private ProductService productService;
public static void main(String[] args) {
Main main= new Main();
main.productService= (ProductService)(new ClassPathXmlApplicationContext("applicationContext.xml")).getBean("productProxy");
//load the product without the name
Product p = main.productService.getProduct();
//load the lazy name
System.out.println(main.productService.getName(p)); //EXCEPTION IS THROWN IN THIS LINE
}
public void setProductService(ProductService productService) {
this.productService= productService;
}
public ProductService getProductService() {
return productService;
}
My applicationContext.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:sca="http://xmlns.oracle.com/weblogic/weblogic-sca">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"><value>oracle.jdbc.driver.OracleDriver</value></property>
<property name="url"><value>jdbc:oracle:thin:@${hostname}:${port}:${schema}</value></property>
<property name="username"><value>${username}</value></property>
<property name="password"><value>${password}</value></property>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="configLocation"><value>hibernate.cfg.xml</value></property>
<property name="configurationClass"><value>org.hibernate.cfg.AnnotationConfiguration</value></property>
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
<property name="allowCreate" value="true"/>
</bean>
<bean id="productDAO" class="product.model.data.ProductDAO" >
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="hibernateInterceptor"
class="org.springframework.orm.hibernate3.HibernateInterceptor">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="productService"
class="product.services.ProductServiceImpl">
<property name="productDAO">
<ref bean="ProductDAO"/>
</property>
</bean>
<bean id="productProxy"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref bean="productService"/>
</property>
<property name="proxyInterfaces">
<value>product.services.ProductService</value>
</property>
<property name="interceptorNames">
<list>
<value>hibernateInterceptor</value>
</list>
</property>
</bean>
</beans>
The exception fragment:
11:59:57,775 [main] DEBUG org.springframework.orm.hibernate3.SessionFactoryUtils - Opening Hibernate Session
11:59:57,775 [main] DEBUG org.hibernate.impl.SessionImpl - opened session at timestamp: 12749723977
11:59:57,777 [main] ERROR org.hibernate.LazyInitializationException - could not initialize proxy - no Session
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:108)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:150)
at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)
Am I right if I assume that the HibernateInterceptor keeps the Hibernate Session Open among the different calls? If I'm so, Why is the session closed after loading the product object?
I read somewhere that I also can use OpenSessionInViewInterceptor, but I can't make it work. How would you add that interceptor to this little example?
Is there any code mistake or missunderstanding on how this work?
Do you know any simple example code I can download to check how this work?
Thanks in advance, Neuquino