Search code examples
jpaentityeclipselinkejb-3.1javadb

Many to Many relationship JPA, EJB and new table in db


i'm working on javaEE (7) Entreprise application with EJB, JPA and JSF2.2 (NetBeans 8.0.2 and GF 4.1) this is my design in JavaDB : 2 tables with a Many to Many relationship so a new table "Avoir" is generated.

a "Document" has several "Critere" and "Critere" can belong to several "Document". my problem is when i generate Entities Classes from Databases with Eclipselink 2.1, i have only a "Document" and "Critere" classes, but no "Avoir" class.

my question is, how can i add row in "Avoir" table ?

NB : this the code of my 2 classes

Critere code :

@Entity
@Table(name = "CRITERE")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Critere.findAll", query = "SELECT c FROM Critere c"),
@NamedQuery(name = "Critere.findByIdcritere", query = "SELECT c FROM Critere c WHERE c.idcritere = :idcritere"),
// Others Query …
public class Critere implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "IDCRITERE")
// Other columns …
@JoinTable(name = "AVOIR", joinColumns = {
    @JoinColumn(name = "IDCRITERE", referencedColumnName = "IDCRITERE")}, inverseJoinColumns = {
    @JoinColumn(name = "IDDOC", referencedColumnName = "IDDOC")})
@ManyToMany
private Collection<Document> documentCollection;
// Other mappings ...

and Document code :

@Entity
@Table(name = "DOCUMENT")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Document.findAll", query = "SELECT d FROM Document d"),
@NamedQuery(name = "Document.findByIddoc", query = "SELECT d FROM Document d WHERE d.iddoc = :iddoc"),
// Other Query …    
public class Document implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "IDDOC")
private Integer iddoc;
// Other columns …

@ManyToMany(mappedBy = "documentCollection")
private Collection<Critere> critereCollection;
// Other mappings …

thank you :)


Solution

  • You don't need to worry about that. @ManyToMany is implemented using a join table (AVOIR in your case), and the persistence provider takes care of wiring it all up in the database. Your responsibility is only to maintain both sides of the relationship, meaning if you add one Critere to a Document, be sure that Document also has that Critere in the list.

    @JoinTable defines the table which is used for relationship, joinColumns attribute defines the column which is a foreign key to source table (CRITERE) and inverseJoinColumns attribute defines the column which is a foreign key to target table (DOCUMENT).

    Document doc = em.find(Document.class, 1L);
    Critere cit = em.find(Critere .class, 1L);
    // you just need to maintain both sides of the relationship
    doc.getCritereCollection().add(crit);
    crit.getDocumentCollection().add(doc);
    em.merge(doc); // not really needed because these are attached entities (if executed inside of transaction)
    

    This will add a row in AVOIR table, with value 1 in both columns.