Bonjour,
Je rencontre un problème de mapping objet/relationnel sur une appli Spring+Hibernate+Mysql. L'archi globale est la suivante:
Couche métier (Spring) --> couche DAO (Spring+Hibernate) --> Beans model (transverse à toute l'application)
Ma gestion de hibernate est entièrement déléguée à Spring et j'utilise des annotations pour mes entités.
Voici le code de mon entité:
Voici le code 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
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
58
59
60
61
62
63
64
65
66
67 @Entity @Table(name = "product", catalog = "my_catalog", uniqueConstraints = @UniqueConstraint(columnNames = "generic_name")) public class Product implements Serializable { private static final long serialVersionUID = -1881936584394110049L; private Integer id; private String genericName; private Set<ProductAvailability> productAvailabilities = new HashSet<ProductAvailability>(0); @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "id", unique = true, nullable = false) public Integer getId() { return this.id; } public void setId(Integer id) { this.id = id; } @Column(name = "generic_name", unique = true, nullable = false, length = 25) public String getGenericName() { return this.genericName; } public void setGenericName(String genericName) { this.genericName = genericName; } @OneToMany(fetch = FetchType.EAGER, mappedBy = "product") public Set<ProductAvailability> getProductAvailabilities() { return this.productAvailabilities; } public void setProductAvailabilities( Set<ProductAvailability> productAvailabilities) { this.productAvailabilities = productAvailabilities; } } @Entity @Table(name = "product_availability", catalog = "my_catalog") public class ProductAvailability implements java.io.Serializable { private static final long serialVersionUID = -2133958619360018974L; private ProductAvailabilityId id; private ProductSize productSize; private Product product; //getters and setters ... } @Embeddable public class ProductAvailabilityId implements java.io.Serializable { private static final long serialVersionUID = -6106195773528063342L; private int refProduct; private int refSize; private int quantity; private String reference; //getters and setters ... }
Et finalement le code sql de creation de bd:
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 public class ProductDaoImpl extends HibernateDaoSupport implements ProductDao { public Product getProductDetailByName(String name, String languageCode) { try { Session session = getHibernateTemplate().getSessionFactory().getCurrentSession(); Criteria crit = session.createCriteria(Product.class); crit.add(Expression.eq("genericName", name)); crit.setProjection(getLocalizedProductDetailByNameProjection(languageCode)); crit.setResultTransformer(Transformers.aliasToBean(Product.class)); Product product = (Product) crit.uniqueResult(); return product; } catch (DataAccessException e) { //error treatment } } private ProjectionList getLocalizedProductDetailByNameProjection( String languageCode) { ProjectionList currentList = Projections.projectionList(); currentList.add(Projections.property("id"), "id"); currentList.add(Projections.property("genericName"), "genericName"); } }
Mon problème maintenant: Quand j'exécute ProductDaoImpl.getProductDetailByName(...) il me rempli bien tous les champs sauf la collection alors que le FetchType est en EAGER.
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 CREATE TABLE product_size( id INTEGER NOT NULL PRIMARY KEY auto_increment, name VARCHAR(15) NOT NULL, short VARCHAR(3) NOT NULL, UNIQUE (name, short) )TYPE=INNODB DEFAULT CHARSET=utf8; CREATE TABLE product( id INTEGER NOT NULL PRIMARY KEY auto_increment, generic_name VARCHAR(25) NOT NULL UNIQUE, )TYPE=INNODB DEFAULT CHARSET=utf8; CREATE TABLE product_availability( ref_product INTEGER NOT NULL, ref_size INTEGER NOT NULL, quantity INTEGER NOT NULL, reference VARCHAR(25) NOT NULL, FOREIGN KEY (ref_product) REFERENCES product(id) ON DELETE CASCADE, FOREIGN KEY (ref_size) REFERENCES product_size(id) ON DELETE CASCADE )TYPE=INNODB DEFAULT CHARSET=utf8;
Pire encore, lorsque je comment les lignes
crit.setProjection(getLocalizedProductDetailByNameProjection(languageCode)); crit.setResultTransformer(Transformers.aliasToBean(Product.class));
la collection est bien remplie avec les objets de disponibilités de produits.
Donc, j'en arrive à la conclusion que c'est la projection qui pose problème, mais je ne vois pas où ...
J'ai essayé de jouer avec avec des instructions comme:
crit.setFetchMode("productAvailabilities", FetchMode.JOIN);
mais ça ne marche pas mieux ...
Quelqu'un aurait-il une idée pourquoi je ne peux pas combiner une projection avec une collection?
Merci d'avance
Partager