persistence@glassfish.java.net

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

From: James Sutherland <jamesssss_at_yahoo.com>
Date: Wed, 12 Sep 2007 07:07:21 -0700 (PDT)

The issue is that you have two mappings for the same column, user and userId.
Unfortunately the JPA does not allow a ManyToOne mapping to be part of a
primary key so you need to duplicate the mapping as you have done. When you
do so you must ensure that the Basic mapping (userId) is the writeable
mapping and the ManyToOne is read-only. The JPA requires that you use the
@PrimaryKeyJoinColumn on the @ManyToOne to accomplish this.

You need to remove the "insertable = false, updatable = false" from your
userId mapping, and either add this to your user mapping, or make it use a
@PrimaryKeyJoinColumn.

You will also need to ensure that your userId value is set to your user's id
before you commit. Since your User is using a sequence id you may need to
call persist on it before assigning it to the ManyToOne, possible even flush
if you are using Identity sequencing. In general having a foreign key as
part of your primary key is something that the JPA spec really does poorly,
so you may be better off using a sequence id in your object.

TopLink Essentials actually does allow a ManyToOne to be used as part of a
primary key without requiring a duplicate basic mapping. Unfortunately this
functionality is not exposed in JPA, although you may be able to configure
it using a DescriptorCustomizer.

Please log a bug in the Glassfish bugtracker for the issue of the error
message not be accurate in this use case. Also feel free to log an
enhancement to have the support for ManyToOne exposed through JPA.

---
http://wiki.java.net/bin/view/People/JamesSutherland James Sutherland 
sud-3 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() {
>     }
> }
> 
> 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;
>     }
> 
> }
> 
> 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
> 
-- 
View this message in context: http://www.nabble.com/Composite-Primary-Key-Mapping-error---Invalid-composite-primary-key-specification-tf4425733.html#a12636330
Sent from the java.net - glassfish persistence mailing list archive at Nabble.com.