问题
I have two tables.
CREATE TABLE profile_table
(
profile_id NUMBER(10,0) PRIMARY KEY,
creator_manager_id NUMBER(10,0),
lastupdate DATE,
description VARCHAR2(255 BYTE),
profile_name VARCHAR2(255 BYTE),
creatorname VARCHAR2(255 BYTE)
);
CREATE TABLE profile_basket_table
(
profile_id NUMBER(10,0),
from_id NUMBER(10,0),
action NUMBER(10,0),
constraint pbt_pk_constraint PRIMARY KEY(profile_id, from_id),
constraint pbt_fk_constraint FOREIGN KEY(profile_id) REFERENCES profile_table(profile_id)
);
I have 1 Profile and * ProfileItem.
1 Profile --- * ProfileItems ( One profile can have Many ProfileItems).
Note : 1. Its a one-to-many relationship from profile to profileItem. 2. Its a unidirectional relationship.
PK for Profile is profile_id.
PK for ProfileItem is a composite primary key ( profile_id, from_id )
Firstly, I would I like to complain that EclipseLink doesnt work like Hibernate :
1st Problem with EclipseLink: Just becasue I have a composite primary key in child entity called ProfileItem, its forcing me to use JoinColumns. I cant use @JoinColumns as other column from_id is not a foreign key to any other table. I initially used same annotation which worked perfectly with hibernate as follows :
@Entity
@Table(name="profile_table")
class Profile {
@Id
@Column(name="profile_id")
private Integer profileId ;
...
/**
* WORKS WITH HIBERNATE AS PERSISTENCE PROVIDER, BUT FAILS WITH ECLIPSELINK
*/
@OneToMany( cascade = CascadeType.ALL )
@JoinColumn( name= "profile_id", referencedColumnName="profile_id" )
private Set<XVMUpdateProfileItem> profileItems = null;
...
}
Above code throws following error with eclipselink :
The @JoinColumns on the annotated element [field profileItems] from the entity class [class arun.ucerelay.datastructures.XVMUpdateProfile] 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 referencedColumnName elements must be specified in each such @JoinColumn.
Some how with several permutations and combinations of @JoinColumn annotation, I managed to get this working for loading profiles and related profile items.
/**
* WORKS WITH ECLIPSELINK AS PERSISTENCE PROVIDER
*/
@OneToMany( cascade = CascadeType.ALL)
@JoinColumns({
@JoinColumn( name= "profile_id", referencedColumnName="profile_id" , insertable = true, updatable = true),
@JoinColumn( name= "profile_id", referencedColumnName="profile_id" , nullable = false)
})
private Set<XVMUpdateProfileItem> profileItems = null;
This doesnt make sense to declare @JoinColumn again...But weirdly it works with eclipselink. This is a bug. Isnt it?
Can anyone tell me if I am missing anything ? Is there any other right way of implementing unidirectional relationship, please tell me.
This is a bug about @JoinColumns isnt it ? Should I log it ?
Is this called "portability" from one persistence provider to another ??????? What is the use of using JPA specification if it doesnt solve portability.
There is a second problem with saving of parent and cascading child items which works with hibernate and doesnt work with eclipselink. Ill post it as a separate question to keep this short and precise.
Thanks. Arun Kandregula
回答1:
This seems to be a bug in the annotation processing. Please log this bug on EclipseLink if it still occurs on the latest version.
Note that @JoinColumn is normally used for @ManyToOne or @OneToOne, not @OneToMany. Normally for a @OneToMany you should have an inverse @ManyToOne and use the mappedBy. Using a @JoinColumn on a @OneToMany is a special type of @OneToMany that maintains the target table's foreign key itself. Since the profile_id is part of your primary key, to be correct you really should have the @ManyToOne back, you could then remove the profileId and just add @Id to the @ManyToOne.
回答2:
i have inherited a code like this (and working fine with hibernate):
@OneToMany @JoinColumn(name="prod_no", referencedColumnName="prod_no") private Collection items;
joinColumn is used for oneToMany ;)
来源:https://stackoverflow.com/questions/5520153/composite-primary-key-selection-what-works-with-hibernate-doesnt-work-with-ecli