2010-04-28 3 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

ответ

1

Сообщение об ошибке кажется довольно ясным: вам нужно объявить три столбца вашего составного ПК как @JoinColum, а для каждого должны быть указаны name и referenceColumnName. Я не проверял отображение, но попробуйте это:

@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

Спасибо за ответ, но я попытался объявить три столбца моего составного ПК как @JoinColum, и это также дало мне ошибку. Ошибка была противоположна первой. Он попросил объявить один первичный ключ, а не три, используя @JoinColumn. В любом случае, я нашел решение! Я собираюсь опубликовать ответ с примером кода прямо сейчас. –

11

Доброе утро,

После долгого дня в поисках, как JPA и @OneToMany работы с композитными ПК, я нашел решение. Чтобы он работал, я использовал параметр mappedBY @OneToMany. Как вы можете видеть в примере кода, я сопоставил набор разрешений с действием атрибута класса Permission. Вот и все! Просто, когда вы это знаете!

FF

Класс действия:

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