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 :

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;
   }
   ...
}
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
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;
   }
 
   ...
}
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
 
@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;
   }
 
   ...
}
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
 
@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;
   }
 
   ...
}
Le problème est que je n'arrive pas à générer d'id pour la classe ProprieteMatiere.

Voici le test JUnit que j'utilise (simplifié) :
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 !!!
Et voici la stack générée :

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 !