Bonjour,
Je développe un site JavaEE avec Struts et Hibernate. Au niveau mapping des données avec la base de données, je dispose de Users (Utilisateurs) et de Functions (Fonctions). Un Utilisateur peut avoir plusieurs Fonctions ("admin", "engineer", etc.).
Introduction au problème :
1) un client demande la page des Utilisateurs.
2) je charge les Utilisateurs dans une liste (via Hibernate).
3) je renvoie cette liste à une page JSP.
4) la page JSP affiche les Utilisateurs, mais lorsqu'elle arrive à l'attribut "functions", elle déclenche une requête via Hibernate (lazy initialization).
Mon problème : j'aimerais trier ces Fonctions, car Hibernate ne semble pas les renvoyer dans le même ordre.
En fait, je ne sais pas à quel moment il est judicieux d'effectuer le tri :
1) lors de la requête Hibernate ? (dans ce cas, comment faire, étant donné que je ne "contrôle" pas la requête car elle se déclenche par "lazy initialization")
2) dans l'Action Struts ? J'ai déjà essayé, mais comme les Utilisateurs et les Fonctions sont mappées par Hibernate, il comprend pas bien mon tri (Collections.sort(list))...
3) dans la page JSP ?
Je sais que ça ne concerne pas spécifiquement Hibernate, mais c'est un problème transverse. Je ne suis pas un expert en Hibernate, et j'ai surtout soif d'expérience et de l'usage (ce qu'on fait d'habitude).
J'ai mis les détails techniques ci-dessous.
En vous remerciant d'avance,
piloupy
---
Hibernate version: 3.2.2
Mapping documents:
hibernate.cfg.xml
Code:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/***</property>
<property name="connection.username">***</property>
<property name="connection.password">***</property>
<!-- JDBC connection pool (use the built-in) -->
<!--
<property name="connection.pool_size">1</property>
-->
<!-- C3P0 connection pool -->
<property name="hibernate.c3p0.min_size">1</property>
<property name="hibernate.c3p0.max_size">5</property>
<property name="hibernate.c3p0.timeout">1800</property>
<property name="hibernate.c3p0.max_statement">50</property>
<property name="connection.autoReconnect">true</property>
<property name="connection.autoReconnectForPools">true</property>
<property name="connection.is-connection-validation-required">true</property>
<property name="connection.release_mode">auto</property>
<!-- SQL dialect -->
<property name="dialect">
org.hibernate.dialect.MySQLInnoDBDialect
</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">
org.hibernate.cache.NoCacheProvider
</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="beans/User.hbm.xml" />
<mapping resource="beans/Function.hbm.xml" />
</session-factory>
</hibernate-configuration>
User.hbm.xmlCode:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="beans.User" table="USER">
<id name="id" column="USER_ID">
<generator class="native" />
</id>
<property name="firstname" column="USER_FIRSTNAME" />
<property name="lastname" column="USER_LASTNAME" />
<property name="userid" column="USER_USERID" unique="true" />
<property name="company" column="USER_COMPANY" />
<property name="email" column="USER_EMAIL" />
<property name="phone" column="USER_PHONE" />
<set name="functions" table="USER_FUNCTION" lazy="false">
<key column="USER_ID" />
<many-to-many column="FUNCTION_ID" class="beans.Function" />
</set>
</class>
</hibernate-mapping>
Function.hbm.xmlCode:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="beans.Function" table="FUNCTION">
<id name="id" column="FUNCTION_ID">
<generator class="native" />
</id>
<property name="name" column="FUNCTION_NAME" unique="true" />
<property name="description" column="FUNCTION_DESCRIPTION" />
<set name="users" table="USER_FUNCTION" inverse="true" lazy="false">
<key column="FUNCTION_ID" />
<many-to-many column="USER_ID" class="beans.User" />
</set>
</class>
</hibernate-mapping>
Java Code :Code:
private static SessionFactory factory = HibernateUtil.getSessionFactory();
public static List<User> getUsers() {
Session session = factory.getCurrentSession();
Transaction tx = session.beginTransaction();
List<User> users = (List<User>) session.createQuery("from User").list();
tx.commit();
return users;
}
JSP Code :- List<User> listUsers : contient les Users rapatriés de la base de données.
Code:
<logic:iterate id="e" indexId="eid" name="listUsers">
<c:forEach items="${e.functions}" var="item" varStatus="status">
<c:out value="${item.name}"/>
</c:forEach>
</logic:iterate>
Hibernate request :Code:
Hibernate: select functions0_.USER_ID as USER1_1_, functions0_.FUNCTION_ID as FUNCTION2_1_, function1_.FUNCTION_ID as FUNCTION1_2_0_, function1_.FUNCTION_NAME as FUNCTION2_2_0_, function1_.FUNCTION_DESCRIPTION as FUNCTION3_2_0_ from USER_FUNCTION functions0_ left outer join FUNCTION function1_ on functions0_.FUNCTION_ID=function1_.FUNCTION_ID where functions0_.USER_ID=?
Name and version of the database you are using: MySQL 4.1.22 Community