2010-04-28 65 views
9

我正在JPA項目上工作。我需要在具有三個主鍵的類上使用@OneToMany映射。你可以在這之後找到錯誤和類。JPA @OneToMany和複合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) 

這裏是我的課的源代碼:

操作:

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

權限:

@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

它看起來像你複製的 'PermissionPK' 上市 '許可' 源代碼。 – Henry 2012-03-16 16:03:07

回答

1

錯誤消息似乎很清楚:您需要聲明您的複合PK的三列爲@JoinColum,並且必須爲每個列指定namereferenceColumnName。我沒有測試的映射,但試試這個:

@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

感謝您的回答,但我試圖將我的複合PK的三列聲明爲@JoinColum,它也給我一個錯誤。錯誤與第一個錯誤相反。它要求使用@JoinColumn聲明一個主鍵,而不是三個。 無論如何,我找到了解決方案!我現在要用代碼示例發佈答案。 – 2010-04-29 07:12:08

11

早上好,

一整天搜索JPA和@OneToMany如何與複合PK後,我沒有找到一個解決方案。爲了使它工作,我使用了@OneToMany的參數mappedBY。正如您在代碼示例中看到的,我將權限集與Permission類的屬性操作進行了映射。就是這樣!當你知道它時簡單!

FF

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; 

權限類

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