2010-04-28 18 views
9

Pracuję nad projektem WZP. Muszę użyć mapowania @OneToMany na klasie, która ma trzy podstawowe klucze. Możesz znaleźć błędy i klasy po tym.JPA @OneToMany i kompozyt PK

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) 

Oto kod źródłowy moich klas:

Działanie:

@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() { 
    } 

Permission:

@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

Wygląda jakbyś powielane w '' Permission kod źródłowy w debiutem '' PermissionPK . – Henry

Odpowiedz

1

Komunikat o błędzie wydaje się całkiem jasny: musisz zadeklarować trzy kolumny twojego złożonego PK jako @JoinColum i dla każdego z nich należy podać name i referenceColumnName. Nie testowałem mapowanie ale spróbuj tego:

@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

Dziękuję za odpowiedź, ale starałem się zadeklarować trzy kolumny z mojego złożonego PK jako @JoinColum i to dało mi również błąd. Błąd był przeciwieństwem pierwszego. Poprosił o zadeklarowanie jednego klucza podstawowego, a nie trzech przy użyciu @JoinColumn. W każdym razie znalazłem rozwiązanie! Zamierzam opublikować teraz odpowiedź z przykładem kodu. –

11

Dzień dobry,

Po długim dniu szukają sposobu JPA i @OneToMany współpracuje z kompozytu PK, znalazłem rozwiązanie. Aby to zadziałało użyłem parametru mappedBY z @OneToMany. Jak widać w przykładowym kodzie, zmapowałem zestaw uprawnień z atrybutem akcji klasy Permission. I to wszystko! Proste, kiedy to wiesz!

FF

Action Klasa:

@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; 

Pozwolenie Klasa

@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;