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.
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:
@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:
@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:
@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:
/**
*
*/
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:
[color=#FF0000]Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: forum.C column: ID_A (should be mapped with insert="false" update="false")[/color]
Pour supprimer cette exception j'ai donc modifier comme suit :
Code:
/** */
@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:
[color=#FF0000]Caused by: org.hibernate.AnnotationException: Mixing insertable and non insertable columns in a property is not allowed: forum.CnumD[/color]
Donc je remodifie comme ca :
Code:
/** */
@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:
/** */
@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