Bonjour,
Alors voila, pour la première fois, je tente d'utiliser les clés primaires composites avec Hibernate (plus précisemment JPA1 mais l'implémentation sous-jacente est Hibernate).
La BD existait déjà et j'ai du faire un reverse pour obtenir mes beans annotés.
En gros j'ai une entity Matiere qui a un ensemble de ProprieteMatiere :
Le bean ProprieteMatiere correspondant qui gère la clé primaire composite entre Matiere et TypePropriete :
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 = "MATIERE") public class Matiere implements Serializable { private Long id; private Set<ProprieteMatiere> proprieteMatieres = new HashSet<ProprieteMatiere>(); @OneToMany(fetch = FetchType.LAZY, mappedBy = "matiere") public Set<ProprieteMatiere> getProprieteMatieres() { return this.proprieteMatieres; } ... }
La classe ProprieteMatiereId générée :
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 @Entity @Table(name = "PROPRIETE_MATIERE") public class ProprieteMatiere implements Serializable { private ProprieteMatiereId id; private TypePropriete typePropriete; private Matiere matiere; @EmbeddedId @GeneratedValue(strategy=GenerationType.AUTO) @AttributeOverrides({ @AttributeOverride(name = "idMatiere", column = @Column(name = "ID_MATIERE")), @AttributeOverride(name = "idTypePropriete", column = @Column(name = "ID_TYPE_PROPRIETE")) }) public ProprieteMatiereId getId() { return this.id; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "ID_TYPE_PROPRIETE", nullable = false, insertable = false, updatable = false) @NotNull public TypePropriete getTypePropriete() { return this.typePropriete; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "ID_MATIERE", nullable = false, insertable = false, updatable = false) @NotNull public Matiere getMatiere() { return this.matiere; } ... }
Et enfin la classe TypePropriete :
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 @Embeddable public class ProprieteMatiereId implements Serializable { private Long idMatiere; private Long idTypePropriete; @Column(name = "ID_MATIERE") public Long getIdMatiere() { return this.idMatiere; } @Column(name = "ID_TYPE_PROPRIETE") public Long getIdTypePropriete() { return this.idTypePropriete; } ... }
Le problème est que je n'arrive pas à générer d'id pour la classe ProprieteMatiere.
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 = "TYPE_PROPRIETE") public class TypePropriete implements Serializable { private Long id; @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_CADEEX") @SequenceGenerator(name="SEQ_CADEEX", sequenceName = "SEQ_CADEEX") @Column(name = "ID_TYPE_PROPRIETE") public Long getId() { return this.id; } ... }
Voici le test JUnit que j'utilise (simplifié) :
Et voici la stack générée :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 Matiere matiere = new Matiere(); // em = EntityManager em.persist(matiere); // insertion OK, id généré typeProprieteMatiere = new TypePropriete(); em.persist(typeProprieteMatiere); // insertion OK, id généré ProprieteMatiere proprieteMatiere = new ProprieteMatiere(); proprieteMatiere.setTypePropriete(typeProprieteMatiere); proprieteMatiere.setMatiere(matiere); em.persist(proprieteMatiere); // KO !!!
javax.persistence.PersistenceException: org.hibernate.id.IdentifierGenerationException: null id generated for:class com.test.entity.ProprieteMatiere
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:637)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:226)
at com.test.persistance.dao.CreateMatiereTest.testCreateMatiere(CreateMatiereTest.java:107)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.hibernate.id.IdentifierGenerationException: null id generated for:class com.test.entity.ProprieteMatiere
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:124)
at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:49)
at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:179)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:61)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:800)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:774)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:778)
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:220)
... 25 more
Quelqu'un aurait une idée ? La je sèche un peu.
Merci d'avance !
Partager