Bonjour à tous,
étant quelque peu novice, je m'emmêle un peu les pinceaux avec Hibernate.
Je cherche à générer une liaison 1-n sous la forme suivante :
1 pays possède plusieurs villes, Une ville est liée à un seul pays.
Au niveau base de données, cela est modélisé par :
T_PAYS
ID
NAME
USER_ID (*)
(etc)
(*) : dans mon exemple, un pays peut être lié à un utilisateur de ma base. Un genre de "pays préféré" pour l'utilisateur, en quelque sorte ...
T_VILLE
ID
ID_PAYS
NAME
(etc)
Au niveau de l'application, j'ai 2 choix :
a) soit d'avoir un "ville.getPays()" : cela j'y arrive; soit d'avoir un "pays.getVilles()" et ça je n'y arrive pas. Par praticité, je préfère avoir la seconde solution, car l'idée est que mon DAO charge mon objet "Pays", avec les "Villes" déjà pré-chargées.
Pour le moment (et un bon moment j'espère), il n'y a pas de problème de mise à jour dans la base : les données sont uniquement en lecture.
J'utilise la version 3.4 d'Hibernate (JAR utilisé "hibernate-entitymanager-3.4.0.GA.jar"), ainsi que Spring. Ma base de données est Oracle.
Voici le code de la classe "Pays" :
Voici le code de la classe Ville:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
27
28
29
30
31 @Entity @Table(name = "T_PAYS") public class Pays implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "pays_seq") @SequenceGenerator(name = "pays_seq", allocationSize = 10, sequenceName = "SEQ_PAYS_ID") private long id; private String name; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "USER_ID", nullable = true) private User user; @Column(name = "PAYS_COMMENT", nullable = true) private String comment; // TODO que dois je specifier ici ??? // Je m'emmêle les pinceaux ! :-/ @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST) @JoinColumn(name = "PAYS_ID", nullable = true) private Set<Ville> villes; public long getId() { return id; } // etc : Getters / Setters en public }
Enfin, la classe de mon DAO :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 @Entity @Table(name = "T_VILLE") public class Ville { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ville_seq") @SequenceGenerator(name = "ville_seq", allocationSize = 10, sequenceName = "SEQ_VILLE_ID") private long id; // note : facultatif, si j'arrivais à charger les villes directement dans un pays ... @Column(name = "PAYS_ID", nullable = false, insertable = false, updatable = false) private Pays pays; // etc : getters / setters }
Bref, comment gérer une liaison 1-n directement dans la classe "Pays", à coup d'annotations ? Que je puisse charger dans mon DAO directement le Pays et ses Villes ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 @Repository public class PaysDAO extends MutableDAOImpl<Pays> { public static Logger LOGGER = Logger.getLogger(PaysDAO.class); /** * Private constructor used to prevent from instantiation. * * Use DAOFactory. */ private PaysDAO () { super(); } public Class<Pays> getModelClass() { return Pays.class; } @SuppressWarnings("unchecked") public Pays findById(int id) throws DAOException { try { String qlString = "select c from Pays c where c.id=:id"; Query query = em.createQuery(qlString); query.setParameter("id", id); return query.getSingleResult(); } catch (Exception e) { LOGGER.error(e.getMessage(), e); throw new DAOException(e); } } @SuppressWarnings("unchecked") public List<Pays> findByName(String name) throws DAOException { try { String qlString = "select c from Pays c where c.name=:name"; Query query = em.createQuery(qlString); query.setParameter("name", name); return query.getResultList(); } catch (Exception e) { LOGGER.error(e.getMessage(), e); throw new DAOException(e); } } @SuppressWarnings("unchecked") public List<Pays> findByUser(long userId) throws DAOException { try { String qlString = "select c from Pays c where c.user.id=:userId"; Query query = em.createQuery(qlString); query.setParameter("userId", userId); return query.getResultList(); } catch (Exception e) { LOGGER.error(e.getMessage(), e); throw new DAOException(e); } } }
Merci d'avance pour vos éclaircissements si vous en avez.
Très cordialement,
Partager