Je sais que cela a été discuté plusieurs fois. Je ne peux pas comprendre comment ce travail ou où est mon erreur.
Je pense que vous donner un exemple réduit est la meilleure façon de vous montrer ce que j'essaie de faire et quelles hypothèses je prends ...Besoin d'aide avec Spring/Hibernate Lazy-loading
J'ai une classe de produit avec un nom. Le nom est une propriété String paresseuse.
Mon OAC:
public abstract class HibernateProductDAO extends HibernateDaoSupport implements ProductDAO
{
public List getAll()
{
return this.getHibernateTemplate().find("from " + this.getDomainClass().getSimpleName());
}
}
Mon interface de service:
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);
}
Mon service Mise en œuvre:
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();
}
}
Ma principale classe:
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;
}
Mon 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>
Le fragment d'exception:
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)
Ai-je raison si je suppose que le HibernateInterceptor maintient la session hibernate ouverte entre les différents appels? Si oui, pourquoi la session est-elle fermée après le chargement de l'objet produit?
J'ai lu quelque part que je peux aussi utiliser OpenSessionInViewInterceptor, mais je ne peux pas le faire fonctionner. Comment ajouterais-tu cet intercepteur à ce petit exemple?
Y at-il une erreur de code ou une mauvaise compréhension de la façon dont cela fonctionne?
Connaissez-vous un exemple de code simple que je peux télécharger pour vérifier comment cela fonctionne?
Merci à l'avance, Neuquino