persistence@glassfish.java.net

Re: Composite Primary Key Mapping error - Invalid composite primary key specification

From: Marina Vatkina <Marina.Vatkina_at_Sun.COM>
Date: Fri, 14 Sep 2007 14:30:35 -0700

This is very strange - Java EE 5 Tutorial has a similar example (see LineItem in
the order-ejb) which has @Id defined before @Column. The only difference is that
the tutorial uses property-based persistence.

Regards,
-marina

sudhakar wrote:
> I found the issue. The @Id annotation in the owning class
> (VelocityUserDefinedField.java) had to be directly on or above the
> field. So where I initially had
>
> @Id
> @Column(name = "FieldNo")
> private int fieldNo;
>
> @Id
> @Column(name = "UserID", nullable = false, insertable = false,
> updatable = false)
> private int userId;
>
> when I changed it to
>
> @Column(name = "FieldNo")
> @Id
> private int fieldNo;
>
> @Column(name = "UserID", nullable = false, insertable = false,
> updatable = false)
> @Id
> private int userId;
>
>
> The error went away. I was able to reproduce it in a different project.
> If someone else can replicate this also, I could file a bug if this is one.
> Thanks
> -sud
>
> wrote:
>
>>I'm following the detailed example posted on this page as the 5th post
>>by ss141213 and have been unable to successfully replicate it in my
>>own code.
>>
>>http://forums.java.net/jive/thread.jspa?threadID=14559
>>
>>My classes are as below:
>>
>>This is my Composite Primary Key class (VelocityUserDefinedFieldPK.java):
>>
>>public class VelocityUserDefinedFieldPK implements Serializable {
>> private static final long serialVersionUID = -2079169439511686165L;
>>
>> private int userId;
>> private int fieldNo;
>>
>> public VelocityUserDefinedFieldPK() {
>> }
>>
>> public VelocityUserDefinedFieldPK(int userId, int fieldNo) {
>> this.userId = userId;
>> this.fieldNo = fieldNo;
>> }
>>
>> @Override
>> public boolean equals(Object otherOb) {
>> if (this == otherOb) {
>> return true;
>> }
>> if (!(otherOb instanceof VelocityUserDefinedFieldPK)) {
>> return false;
>> }
>> VelocityUserDefinedFieldPK other =
>>(VelocityUserDefinedFieldPK) otherOb;
>> return (userId == 0 ? other.userId == 0 : userId == other.userId)
>> && fieldNo == other.fieldNo;
>> }
>>
>> @Override
>> public int hashCode() {
>> int hash = 7; // arbitrary
>> hash = 31 * hash + userId;
>> hash = 31 * hash + (fieldNo == 0 ? 0 : fieldNo);
>> return hash;
>> }
>>
>> @Override
>> public String toString() {
>> return "" + userId + "-" + fieldNo;
>> }
>>}
>>
>>This is the owning class in the Many to One relationship
>>(VelocityUserDefinedField.java):
>>
>>@Entity
>>@IdClass(brazos.ldap.ejb.jobs.domain.VelocityUserDefinedFieldPK.class)
>>@Table(name = "UserDefinedFields")
>>public class VelocityUserDefinedField implements Serializable {
>>
>> private static final long serialVersionUID = 6690178500638415700L;
>>
>> @Id
>> @Column(name = "FieldNo")
>> private int fieldNo;
>>
>> @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER,
>>optional = false)
>> @JoinColumn(name = "UserID", referencedColumnName = "HostUserId",
>>nullable = false)
>> private VelocityUser user;
>>
>> @Id
>> @Column(name = "UserID", nullable = false, insertable = false,
>>updatable = false)
>> private int userId;
>>
>> @Column(name = "Value")
>> private String value;
>>
>> public VelocityUserDefinedField() {
>> }
>>
>> public VelocityUserDefinedField(VelocityUser user, int fieldNo,
>>String value) {
>> this.fieldNo = fieldNo;
>> this.value = value;
>> this.user = user;
>> userId = user.id;
>> }
>>
>> public VelocityUser getUser() {
>> return user;
>> }
>>
>> public void setUser(VelocityUser user) {
>> this.user = user;
>> }
>>
>> public String getValue() {
>> return value;
>> }
>>
>> public void setValue(String value) {
>> this.value = value;
>> }
>>
>> public int getFieldNo() {
>> return fieldNo;
>> }
>>
>> public void setFieldNo(int fieldNo) {
>> this.fieldNo = fieldNo;
>> }
>>
>> public int getUserId() {
>> return userId;
>> }
>>
>> public void setUserId(int userId) {
>> this.userId = userId;
>> }
>>
>>}
>>
>>This is the inverse class in the Many to One relationship
>>(VelocityUser.java):
>>
>>@Table(name = "Users")
>>@Entity
>>public class VelocityUser implements Serializable {
>>
>> private static final long serialVersionUID = -7002789763335653579L;
>>
>> @Id
>> @GeneratedValue(strategy = GenerationType.IDENTITY)
>> @Column(name = "HostUserId")
>> int id;
>>
>> @Column(name = "FirstName")
>> String firstName;
>>
>> @Column(name = "LastName")
>> String lastName;
>>
>> @OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
>> Set<VelocityUserDefinedField> userDefinedFields;
>>
>> public VelocityUser() {
>> }
>>
>> public String getFirstName() {
>> return firstName;
>> }
>>
>> public void setFirstName(String firstName) {
>> this.firstName = firstName;
>> }
>>
>> public String getLastName() {
>> return lastName;
>> }
>>
>> public void setLastName(String lastName) {
>> this.lastName = lastName;
>> }
>>
>> public int getId() {
>> return id;
>> }
>>
>> public Set<VelocityUserDefinedField> getUserDefinedFields() {
>> return userDefinedFields;
>> }
>>
>> public void setUserDefinedFields(
>> Set<VelocityUserDefinedField> userDefinedFields) {
>> this.userDefinedFields = userDefinedFields;
>> }
>>}
>>
>>
>>
>>When I attempt to call any of the persistence methods I get the
>>following error message:
>>
>>Internal Exception: javax.persistence.PersistenceException: Exception
>>[TOPLINK-28018] (Oracle TopLink Essentials - 2.0 (Build b58g-fcs
>>(09/07/2007))):
>>oracle.toplink.essentials.exceptions.EntityManagerSetupException
>>Exception Description: predeploy for PersistenceUnit [velocityPU] failed.
>>Internal Exception: Exception [TOPLINK-7150] (Oracle TopLink
>>Essentials - 2.0 (Build b58g-fcs (09/07/2007))):
>>oracle.toplink.essentials.exceptions.ValidationException
>>Exception Description: Invalid composite primary key specification.
>>The names of the primary key fields or properties in the primary key
>>class [brazos.ldap.ejb.jobs.domain.VelocityUserDefinedFieldPK] and
>>those of the entity bean class [class
>>brazos.ldap.ejb.jobs.domain.VelocityUserDefinedField] must correspond
>>and their types must be the same. Also, ensure that you have specified
>>id elements for the corresponding attributes in XML and/or an @Id on
>>the corresponding fields or properties of the entity class.
>> at
>>oracle.toplink.essentials.exceptions.PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(PersistenceUnitLoadingException.java:143)
>> at
>>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider.createEntityManagerFactory(EntityManagerFactoryProvider.java:169)
>> at
>>javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:110)
>> at
>>javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:83)
>>
>>
>>As you will notice the fields in the Primary Key class,
>>VelocityUserDefinedFieldPK.java (userId and fieldNo - both int type)
>>do match the fields in the entity class (VelocityUserDefinedField.java).
>>
>>I'd appreciate any help in troubleshooting this.
>>Thanks
>>
>>-sud
>>
>>------------------------------------------------------------------------
>>Tonight's top picks. What will you watch tonight? Preview the hottest
>>shows
>><http://us.rd.yahoo.com/tv/mail/tagline/tonightspicks/evt=48220/*http://tv.yahoo.com/%20>
>>on Yahoo! TV.