Newsgroup: it.comp.java
Titolo: EJB3 composite Key e foreign Key

Salve
Ho  due tabelle padre e figlio
parent con i campi parentID e value
child con childID parentID e value
Ho creato due Entity Bean cosi composti
Child1PK .java
@Embeddable
public class Child1PK implements Serializable {
    @Column(name = "PARENTID", nullable = false)
    private int parentid;
    @Column(name = "IDCHILD1", nullable = false)
    private int idchild1;
.................... i soliti metodi get set hashcode
}
Child1.java
@Entity
@Table(name = "CHILD1")
@NamedQueries({@NamedQuery(name = "Child1.findByParentid", query =
"SELECT c FROM Child1 c WHERE c.child1PK.parentid = :parentid"),
@NamedQuery(name = "Child1.findByIdchild1", query = "SELECT c FROM
Child1 c WHERE c.child1PK.idchild1 = :idchild1"), @NamedQuery(name =
"Child1.findByValue", query = "SELECT c FROM Child1 c WHERE c.value
= :value")})
public class Child1 implements Serializable {
    private static final long serialVersionUID = 1L;
    @EmbeddedId
    protected Child1PK child1PK;
    @Column(name = "VALUE")
    private String value;
    @JoinColumn(name = "PARENTID", referencedColumnName = "PARENTID",
insertable = false, updatable = false)
    @ManyToOne
    private Parent parent;
.............................
}
parent.java
@Entity
@Table(name = "PARENT")
@NamedQueries({@NamedQuery(name = "Parent.findByParentid", query =
"SELECT p FROM Parent p WHERE p.parentid = :parentid"),
@NamedQuery(name = "Parent.findByValue", query = "SELECT p FROM Parent
p WHERE p.value = :value")})
public class Parent implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "PARENTID", nullable = false)
    private Integer parentid;
    @Column(name = "VALUE")
    private String value;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "parent")
    private Collection<Child1> child1Collection;
}
Queste classi le invoco cosi:
       Child1 child1 = new Child1();
        child1.setValue("QQQ");
        Parent parent = new Parent();
        parent.setValue("aaa");
        child1.setParent(parent);
        parent.getChild1Collection().add(child1);
        em.persist(parent);
Mi dice che parentID dentro l entity della child1 non è valorizzata.
IO credo che questo sia dovuto a insertable e updatable false dentro
child1
 @JoinColumn(name = "PARENTID", referencedColumnName = "PARENTID",
insertable = false, updatable = false)
Ma se li tolgo non riesco a deployare perche dice che c'è un errore
sulla definizione PARENTID
Non riesco a venirne a capo
please please


Quale persistence provider usi (toplink, jpa, hibernate, etc)?
Può incollare lo stacktrace dell'eccezione?
Magari il problema è dovuto a qualche operazione lazy


Uso Hibernate.
L'eccezione è:
Caused by: org.hibernate.id.IdentifierGenerationException: ids for
this class must be manually assigned before calling save():
com.accenture.mvno.customer.Parent


Penso che il problema sia nel'id dell Entity Parent.
Tale id infatti tu non lo setti esplicitamente e ciò causa
l'eccezione.
Ciò mi fà pensare che tu abbia usato nel tuo db un autoincrement e ti
aspetti che in fase di persit tale id sia generato, ma così non và.
Devi dire a hibernate che  per PARENTID deve preoccuparsi lui della
generazione dell'id
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "PARENTID", nullable = false)
Spero di averci visto bene!!
--
Articoli ed Esempi su
[Java EE, EJB, Servlet, JSP, WebService, Glassfish, Java ME etc]
http://programmaremobile.blogspot.com


Ops su @GeneratedValue hai perfettamente ragione, mia dimenticanza ;)
cmq l eccezione rimane sempre la stessa
ps grazie per la disponibilità

Quando chiami
parent.getChild1Collection().add(child1)
la collection in che stato è.. è già inizializzata?
--
Articoli ed Esempi su
[Java EE, EJB, Servlet, JSP, WebService, Glassfish, Java ME etc]
<a href="
http://programmaremobile.blogspot.com
">http://
programmaremobile.blogspot.com
 </a>


La inizializzo io,   ti riporto il codice completo di come la invoco
Queste classi le invoco cosi:
       Child1 child1 = new Child1();
        child1.setValue("QQQ");
        Parent parent = new Parent();
        parent.setValue("aaa");
        child1.setParent(parent);
        List<Child1> list = new ArrayList<Child1>();
        list.add(child1);
        parent.setChild1Collection(list);
        em.persist(parent);
La cosa strana è che se io nn definisco primary key PARENTID in child1
tutto funziona, quindi vengono inseriti sia padre che figlio
corretamente valorizzate


Il problema potrebbe essere sempre lo stesso: "La generazione in
automatico dell'id"
Riguardo parent non hai più bisogno di assegnare esplicitamente un id
in quanto usi l'annotation di cui parlavamo prima:@GeneratedValue
Ma riguardo Child il problema rimane ed essendo una chiave composta
devi o creare un generatore automatico(con hibernate credo sia
possibile) o assegnare esplicitamente la chiave.
Quindi aggiungendo
 Child1PK key = new Child1PK(PARENTID, IDCHILD)
 Child1 child1 = new Child1(key);
...
...
a conferma di ciò l'eccezione dice:



mmm Ok
per quanto riguarda IDCHILD lo posso assegnare a mano, ad esempio gli
do 2, ma per quanto riguarda PARENTID cosa gli assegno?
Cioè
 Child1PK key = new Child1PK(PARENTID, 2);
  Child1 child1 = new Child1(key);
Se ho ben capito tu dici di assegnare a PARENTID (ipotizzando un
inserimento anche del padre) un valore tramite un generatore
automatico, ma come si fa un generatore automatico in Hibernate?


Ho trovato come si crea il generatore automatico, ora provo mille
thanks


Alla fine ho risolto in con queste modifiche al codice senza usare il
generatore automatico:
Nel file Child1PK .java
 @JoinColumn(name = "PARENTID", referencedColumnName = "PARENTID")
    @ManyToOne
    private Parent idparent;
invoco le classi cosi
        Child1PK child1PK = new Child1PK();
       ...............
      ..............
       child1PK.setParent(parent);
       child1PK.setIdchild1(3);
       child1.setChild1PK(child1PK);
       .................
Grazie per il supporto
ciao