2010-04-28 15 views
9

Sto lavorando a un progetto JPA. Devo utilizzare un mapping @OneToMany su una classe che ha tre chiavi primarie. Puoi trovare gli errori e le classi dopo questo.JPA @OneToMany e PK composito

javax.persistence.PersistenceException: No Persistence provider for EntityManager named JTA_pacePersistence: Provider named oracle.toplink.essentials.PersistenceProvider threw unexpected exception at create EntityManagerFactory: 
javax.persistence.PersistenceException 
javax.persistence.PersistenceException: Exception [TOPLINK-28018] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.EntityManagerSetupException 
Exception Description: predeploy for PersistenceUnit [JTA_pacePersistence] failed. 
Internal Exception: Exception [TOPLINK-7220] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.ValidationException 
Exception Description: The @JoinColumns on the annotated element [private java.util.Set isd.pacepersistence.common.Action.permissions] from the entity class [class isd.pacepersistence.common.Action] is incomplete. When the source entity class uses a composite primary key, a @JoinColumn must be specified for each join column using the @JoinColumns. Both the name and the referenceColumnName elements must be specified in each such @JoinColumn. 
    at oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:643) 
    at oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider.createEntityManagerFactory(EntityManagerFactoryProvider.java:196) 
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:110) 
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:83) 
    at isd.pacepersistence.common.DataMapper.(Unknown Source) 
    at isd.pacepersistence.server.MainServlet.getDebugCase(Unknown Source) 
    at isd.pacepersistence.server.MainServlet.doGet(Unknown Source) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:718) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:831) 
    at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:411) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:290) 
    at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:271) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:202) 

Ecco il codice sorgente dei miei corsi:

Azione:

@Entity 
@Table(name="action") 
public class Action { 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int num; 

    @ManyToOne(cascade= { CascadeType.PERSIST, CascadeType.MERGE, 
     CascadeType.REFRESH }) 
    @JoinColumn(name="domain_num") 
    private Domain domain; 

    private String name; 
    private String description; 

    @OneToMany 
    @JoinTable(name="permission", joinColumns= { @JoinColumn(name="action_num", referencedColumnName="action_num", nullable=false, updatable=false) }, inverseJoinColumns= { @JoinColumn(name="num") }) 
    private Set<Permission> permissions; 

    public Action() { 
    } 

permesso:

@SuppressWarnings("serial") 
@Entity 
@Table(name="permission") 
public class Permission implements Serializable { 

    @EmbeddedId 
    private PermissionPK primaryKey; 

    @ManyToOne 
    @JoinColumn(name="action_num", insertable=false, updatable=false) 
    private Action action; 

    @ManyToOne 
    @JoinColumn(name="entity_num", insertable=false, updatable=false) 
    private isd.pacepersistence.common.Entity entity; 

    @ManyToOne 
    @JoinColumn(name="class_num", insertable=false, updatable=false) 
    private Clazz clazz; 

    private String kondition; 

    public Permission() { 
    } 

PermissionPK:

@SuppressWarnings("serial") 
@Entity 
@Table(name="permission") 
public class Permission implements Serializable { 

    @EmbeddedId 
    private PermissionPK primaryKey; 

    @ManyToOne 
    @JoinColumn(name="action_num", insertable=false, updatable=false) 
    private Action action; 

    @ManyToOne 
    @JoinColumn(name="entity_num", insertable=false, updatable=false) 
    private isd.pacepersistence.common.Entity entity; 

    @ManyToOne 
    @JoinColumn(name="class_num", insertable=false, updatable=false) 
    private Clazz clazz; 

    private String kondition; 

    public Permission() { 
    } 
+3

Sembra che tu abbia duplicato il codice sorgente 'permesso' nella lista del 'PermissionPK' . – Henry

risposta

1

Il messaggio di errore sembra abbastanza chiaro: è necessario dichiarare le tre colonne del PK composito come @JoinColum e devono essere specificati name e referenceColumnName per ciascuno. Non ho prove, ma la mappatura provare questo:

@OneToMany 
@JoinTable(name="permission", joinColumns= { 
    @JoinColumn(name="col1", referencedColumnName="col1", nullable=false, updatable=false), 
    @JoinColumn(name="col2", referencedColumnName="col2", ...), 
    @JoinColumn(name="col3", referencedColumnName="col3", ...) 
}, inverseJoinColumns= { @JoinColumn(name="num") }) 
private Set<Permission> permissions; 
+1

Grazie per la tua risposta, ma ho provato a dichiarare le tre colonne del mio PK composito come @JoinColum e mi ha dato anche un errore. L'errore era l'opposto del primo. Ha chiesto di dichiarare una singola chiave primaria e non tre utilizzando @JoinColumn. Ad ogni modo, ho trovato la soluzione! Ho intenzione di pubblicare una risposta con un esempio di codice adesso. –

11

Buongiorno,

Dopo una lunga giornata alla ricerca di come APP e @OneToMany funziona con composito PK, ho trovato una soluzione. Per farlo funzionare, ho usato il parametro mappedBY di @OneToMany. Come puoi vedere nell'esempio di codice, ho mappato il Set of Permission con l'azione attribute della classe Permission. E questo è tutto! Semplice quando lo sai!

FF

Class Action:

@Entity 
@Table(name="action") 
public class Action { 

    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    private int num; 

    @ManyToOne(cascade= { CascadeType.PERSIST, CascadeType.MERGE, 
     CascadeType.REFRESH }) 
    @JoinColumn(name="domain_num") 
    private Domain domain; 

    private String name; 
    private String description; 

    @OneToMany(mappedBy="action") 
    private Set<Permission> permissions; 

permesso Classe

@SuppressWarnings("serial") 
@Entity 
@Table(name="permission") 
public class Permission implements Serializable { 

    @EmbeddedId 
    private PermissionPK primaryKey; 

    @ManyToOne 
    @JoinColumn(name="action_num", insertable=false, updatable=false) 
    private Action action; 
Problemi correlati