Bonjour !
Je suis débutant sur la technologie Hibernate et je n'arrive pas a trouver de réponse a ce problème bien précis dans les différents forums et tutoriaux donc je me permets d'en créer un nouveau.

(Copie du post posté aussi sur le forum hibernate a cette adresse : https://forum.hibernate.org/viewtopi...f=11&t=1000712

Voici ce que je voudrais obtenir comme tables avec mon code :


J'ai donc crée les classes comme suit (je vous fait abstraction des getters et setters qui ne possèdent aucunes annotations :

Classe A
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
 
@Entity
@Table( name = "TABLE_A")
public class A implements Serializable
{
 
    /** Auto generated id of the table. */
    @Id
    @SequenceGenerator( name = "SEQ_ID_A_GEN", sequenceName = "SEQ_ID_A", initialValue = 1, allocationSize = 1 )
    @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "SEQ_ID_A_GEN" )
    @Column( name = "ID_A", nullable = false )
    private Integer                       idA;
 
    /**     */
    @Column( name = "NAME_A")
    private String                        name;
 
    /**     */
    @OneToMany( cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "pkB.objectA" )
    private List<B>            listOfB           = new ArrayList<B>();
 
    /**     */
    @OneToMany( cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "pkD.objectA" )
    private List<D>            listOfD           = new ArrayList<D>();
 
    /**     */
    @OneToMany( cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "pkE.objectA" )
    private List<E>            listOfE           = new ArrayList<E>();
 
 
    /**
     * Constructor without parameters.
     */
    public A()
    {
    }
 
   ...
}
Classe B :
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
 
@Entity
@Table( name = "TABLE_B" )
@AssociationOverrides( { @AssociationOverride( name = "pkB.objectA", joinColumns = @JoinColumn( name = "ID_A" ) ) } )
public class B implements Serializable
{
    /** Multiple Identity for this table. */
    @EmbeddedId
    private BPrimaryKey pkB = new BPrimaryKey();
 
    /**     */
    @Column( name = "NAME_B" )
    private String      name;
 
    /**     */
    @OneToMany( fetch = FetchType.LAZY, mappedBy = "pkC.objectB" )
    private List<C>     listOfC = new ArrayList<C>();
 
    /**
     * Constructor without parameters.
     */
    public B()
    {
    }
 
 
 
    //------------------------------------------------------------------------------
    // ---
    // --- Class name:  BPrimaryKey
    // --- Creation:    2 nov. 2009
    /**
     * <p>Title : BPrimaryKey </p>
     * <p>Description : <p> 
     */
    // ---
    //------------------------------------------------------------------------------
    @Embeddable
    public static class BPrimaryKey implements Serializable
    {
 
        /**     */
        @ManyToOne( fetch = FetchType.LAZY )
        private A       objectA;
 
        /** Number of the sequence. */
        @Column( name = "ID_B" )
        private Integer idB;
 
        /**
         * Constructor without parameters.
         */
        public BPrimaryKey()
        {
        }
 
   }
}
Les Classe D et E sont identiques à la classe B (mis a part la liste de C)

et Classe C :
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
 
@Entity
@Table( name = "TABLE_C" )
@AssociationOverrides( { @AssociationOverride( name = "pkC.objectB", joinColumns = {
                                                                                    @JoinColumn( name = "ID_A" ),
                                                                                    @JoinColumn( name = "ID_B" ) } ) } )
public class C implements Serializable
{
    /** Multiple Identity for this table. */
    @EmbeddedId
    private CPrimaryKey pkC = new CPrimaryKey();
 
    /**     */
    @Column( name = "NAME_C" )
    private String      name;
 
    /**  */
    @OneToOne( cascade = CascadeType.ALL )
    @JoinColumns( {
            @JoinColumn( name = "ID_A", referencedColumnName = "ID_A" ),
            @JoinColumn( name = "NUM_D", referencedColumnName = "ID_D" ) } )
    private D           numD;
 
    /**  */
    @OneToOne( cascade = CascadeType.ALL )
    @JoinColumns( {
            @JoinColumn( name = "ID_A", referencedColumnName = "ID_A" ),
            @JoinColumn( name = "NUM_E", referencedColumnName = "ID_E" ) } )
    private E           numE;
 
    /**
     * Constructor without parameters.
     */
    public C()
    {
    }
 
 
 
 
    @Embeddable
    public static class CPrimaryKey implements Serializable
    {
 
        /**     */
        @ManyToOne( fetch = FetchType.LAZY )
        private B       objectB;
 
        /** Number of the sequence. */
        @Column( name = "ID_C" )
        private Integer idC;
 
        /**
         * Constructor without parameters.
         */
        public CPrimaryKey()
        {
        }
 
 
    }
 
}
Code JUNIT de test :
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
 * 
 */
 
public class TestBase
{
 
    private static EntityManager        em;
 
    private static EntityManagerFactory emf;
 
    @BeforeClass
    public static void setUpBeforeClass() throws Exception
    {
 
        emf = Persistence.createEntityManagerFactory( "sample" );
 
    }
 
    @AfterClass
    public static void tearDownAfterClass() throws Exception
    {
 
        emf.close();
 
    }
 
    @Before
    public void setUp() throws Exception
    {
 
        em = emf.createEntityManager();
 
    }
 
    @After
    public void tearDown() throws Exception
    {
 
        em.close();
 
    }
 
    @Test
    public void testRemplissage()
    {
        EntityTransaction tx = em.getTransaction();
 
        tx.begin();
 
        A objA = new A();
 
        objA.setName("New Object A");
 
        em.persist( objA );
 
 
        B objB = new B();
 
        objB.setName( "New Object B" );
        objB.setObjectA( objA );
 
        //objB.getPkB().setIdA( objA.getIdA() );
        objB.getPkB().setIdB( 1 );
 
        objA.getListOfB().add( objB );
 
        em.persist( objB );
 
 
        D objD = new D();
 
        objD.setName( "New Object D" );
        objD.setObjectA( objA );
 
        objD.getPkD().setIdD( 1 );
 
        objA.getListOfD().add( objD );
 
        em.persist( objD );
 
 
        E objE = new E();
 
        objE.setName( "New Object E" );
        objE.setObjectA( objA );
 
        objE.getPkE().setIdE( 1 );
 
        objA.getListOfE().add( objE );
 
        em.persist( objE );
 
 
        C objC = new C();
 
        objC.setName( "New Object C" );
        objC.setObjectB( objB );
 
        objC.setNumD( objD );
        objC.setNumE( objE );
 
        objC.getPkC().setIdC( 1 );
 
        objB.getListOfC().add( objC );
 
        em.persist( objC );
 
 
        tx.commit();
    }
 
}
Le problème avec ce code c'est que j'obtiens une exception :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: forum.C column: ID_A (should be mapped with insert="false" update="false")
Pour supprimer cette exception j'ai donc modifier comme suit :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
/**  */
    @OneToOne( cascade = CascadeType.ALL )
    @JoinColumns( {
            @JoinColumn( name = "ID_A", referencedColumnName = "ID_A", insertable = false, updatable = false ),
            @JoinColumn( name = "NUM_D", referencedColumnName = "ID_D" ) } )
    private D           numD;
 
    /**  */
    @OneToOne( cascade = CascadeType.ALL )
    @JoinColumns( {
            @JoinColumn( name = "ID_A", referencedColumnName = "ID_A", insertable = false, updatable = false ),
            @JoinColumn( name = "NUM_E", referencedColumnName = "ID_E" ) } )
    private E           numE;
Mais là j'obtiens :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
Caused by: org.hibernate.AnnotationException: Mixing insertable and non insertable columns in a property is not allowed: forum.CnumD
Donc je remodifie comme ca :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
/**  */
    @OneToOne( cascade = CascadeType.ALL )
    @JoinColumns( {
            @JoinColumn( name = "ID_A", referencedColumnName = "ID_A", insertable = false, updatable = false ),
            @JoinColumn( name = "NUM_D", referencedColumnName = "ID_D", insertable = false, updatable = false ) } )
    private D           numD;
 
    /**  */
    @OneToOne( cascade = CascadeType.ALL )
    @JoinColumns( {
            @JoinColumn( name = "ID_A", referencedColumnName = "ID_A", insertable = false, updatable = false ),
            @JoinColumn( name = "NUM_E", referencedColumnName = "ID_E", insertable = false, updatable = false ) } )
    private E           numE;
Mon code marche, je n'ai bien qu'un seul ID_A mais je n'ai pas ce que je veux car je n'obtiens pas mon NUM_D ni mon NUM_E comme j'ai insertable et updatable a false.

Pour les obtenir je suis obligé de faire :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
/**  */
    @OneToOne( cascade = CascadeType.ALL )
    @JoinColumns( {
            @JoinColumn( name = "ID_A_D", referencedColumnName = "ID_A" ),
            @JoinColumn( name = "NUM_D", referencedColumnName = "ID_D" ) } )
    private D           numD;
 
    /**  */
    @OneToOne( cascade = CascadeType.ALL )
    @JoinColumns( {
            @JoinColumn( name = "ID_A_E", referencedColumnName = "ID_A" ),
            @JoinColumn( name = "NUM_E", referencedColumnName = "ID_E" ) } )
    private E           numE;
Et voici ce que j'obtiens avec ce code :




Comment faire pour récupérer mes numéros D et E ? ou comment faire comprendre a hibernate que mes 3 ID_A sont les mêmes comme sur le premier schéma ?

Merci

PS : Vous pouvez trouver un zip complet du projet eclipse a cette adresse : http://dl.free.fr/qIcCi23eL