Bonjour à tous.
Je suis en train de débuter dans le développement web en J2EE et j'ai décidé de créer une application toute bête pour me permettre de mieux comprendre les concepts et les détails techniques.
J'ai une base de données mySQL qui contient une seule table "Customer" toute simple avec trois colonnes "ID"(int), "NAME"(string) et "ACCOUNT"(int).
J'ai choisi d'appliquer une architecture 3 tiers avec une couche web (qui utilise struts), une couche métier et une couche d'accès aux données(qui utilise hibernate). Ici on ne s'intéressera qu'aux deux dernières vu que mon problème vient de la couche d'accès aux données.
Pour utiliser hibernate j'ai choisi d'utiliser la partie du framework spring qui lui est dédié et plus particulièrement la classe HibernateDaoSupport.
Alors pour commencer j'ai un bean de données :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public class Customer {
private int id;
private String name;
private int account;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAccount() {
return account;
}
public void setAccount(int account) {
this.account = account;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
} |
Le mapping avec la bdd est défini avec un fichier hbm.xml :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <hibernate-mapping package="hibernate">
<class name="com.infotel.example.dao.model.Customer" table="customer">
<id name="id" type="int" unsaved-value="-1">
<column name="customerId" />
<generator class="increment" />
</id>
<property name="name" type="string">
<column name="customerName" length="45" not-null="true" />
</property>
<property name="account" type="int">
<column name="customerAccount" not-null="true" />
</property>
</class>
</hibernate-mapping> |
Pour remplir les objets de type Customer j'utilise l'objet suivant qui hérite de HibernateDaoSupport et qui implémente une interface toute simple appelée ICustomerDAO (je la met pas ici, elle apporte rien de plus).
Code:
1 2 3 4 5 6 7 8 9 10
| public class CustomerDAOHibernate extends HibernateDaoSupport implements ICustomerDAO {
@Override
public Customer getCustomerById(int id) {
Customer instance = (Customer) getHibernateTemplate().load(Customer.class, id);
return instance;
}
} |
Enfin dans la couche métier je fais appel à CustomerDAOHibernate pour obtenir des instances de ICustomer. Et c'est là que le problème apparaît. Je commence par créer une instance de ICustomer avec mon DAO.
Customer customer = customerDAO.getCustomerById(id);
Puis, 2 lignes plus loin, quand j'essaie de récupérer le contennu de mon objet Customer avec cette ligne :
customer.getAccount();
Il me renvoie une erreur LazyInitializationException: could not initialize proxy - the owning Session was closed
Apparemment la session est fermée au moment où j'appelle getAccount() mais je trouve ça bizarre vu qu'elle est présente deux lignes plus haut dans le getCustomerById().
J'ai vu pas mal de choses en cherchant sur le net qui parlaient d'Interceptors ou de Transaction managers mais je n'ai rien trouvé qui puisse m'expliquer clairement 1) Pourquoi ma session disparait tout d'un coup 2) Comment régler le problème simplement tout en gardant la propriété "lazy".
Si quelqu'un a une bonne expérience en hibernate intégré dans Spring j'aimerais bien avoir son avis.