• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Question about composite primary key in JPA.

 
Mellon Sun
Ranch Hand
Posts: 126
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When I am reading the book "Beginning EJB3 Application Development", I write an entity to taste the composite primary key.

package com.mellon.jpa;

@Entity
public class MEnergy implements Serializable {
@Id
private String year;
@Id
private String month;
private double energy;
public MEnergy(){}
public MEnergy(String year, String month, double value){
this.year = year;
this.month = month;
this.energy = value;
}

@Override
public boolean equals(Object obj) {... }

@Override
public int hashCode() {... }

}

As the above, I did not offer a composite key class and just annotated the year and month field with @Id, but that works. A table named MEnergy was created:
NAME TYPE Nullable
YEARVARCHAR2(255)N
MONTHVARCHAR2(255)N
ENERGYNUMBER(19,4)Y

and the YEAR,MONTH are defined as composited key.

I supposed my code doesn't finished yet and doesn't conform to the specification, can anybody help me to figure it out?
 
Mellon Sun
Ranch Hand
Posts: 126
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
OK, maybe my post is too long.

The fact is I didn't define a primary key class but the composite primary key works well, is that normal?
 
Chandra Bhatt
Ranch Hand
Posts: 1710
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Mellon,

No going in much detail, but it looks to me as it should give error as
redundant use of @Id annotation for a field in a class in normal use case. Is
that right?
[ November 30, 2008: Message edited by: Chandra Bhatt ]
 
Mellon Sun
Ranch Hand
Posts: 126
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No error occured. I created an entity and persist it into the database with no error.
 
Amandeep Singh
Ranch Hand
Posts: 850
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mellon this way is also fine.

Actually there are more than 1 way to define composite key's.

1) Can use @Id more than 1 time on different field's or properties.

2) Can use @Embeddable class, and declare @Id inside that, then use this @Embedded in your concerned class. It will also make up composite keys.
 
Karnati Sudhakar
Ranch Hand
Posts: 270
Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If the composite primary key class is mapped to multiple fields or properties of the entity class,
the names of primary key fields or properties in the primary key class and those of the entity
class must correspond and their types must be the same.


from the persistence specification(2.1.4) document.

Regards
Sudhakar
 
Amol Nayak
Ranch Hand
Posts: 218
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Karnati Sudhakar
quote:
--------------------------------------------------------------------------------
If the composite primary key class is mapped to multiple fields or properties of the entity class,
the names of primary key fields or properties in the primary key class and those of the entity
class must correspond and their types must be the same.
--------------------------------------------------------------------------------



from the persistence specification(2.1.4) document.



This case case in the specification is the one where we define a primary key class using @IdClass annotation.

Since in the example posted by Mellon, we have two @Id annotations and no @IdClass annotation i see no way to find the entity using EntityManager.find.
[ December 02, 2008: Message edited by: Amol Nayak ]
 
Mellon Sun
Ranch Hand
Posts: 126
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
All I want is trying to experience the composite key rules. Three books I read, Manning-EJB3 in Action,OReilly-Enterprise JavaBeans 3.0,Appress-Beginning EJB3 Application Development, sured me that there are two ways to create composite key for an entity.

One is write a PK class, which should be serializable, should implements equals and hashCode methods properly and contains exactly the composite pk fields; then use @IdClass to annotate this pk class to the entity and at the same time the composite pk fields also need to be declared in this Entity class.

The other is write a class annotated with @Embeddable which also contains exactly the composite pk fields and also need to implment the equals and hashCode method properly. The different is this class need not to be seriablizable. After finish, this class should be annotated with @EmbeddedId as a field in the Entity class.

Occasionally, when I was trying the first strategy, I had not write the "necessary" PK class yet but only annotated the composite pk fields in my entity, I ran the project and the table was generated by toplink properly and the entity was persisted well too.

I don't know how to understand this. I step into the ambiguous part of JPA?
 
Ralph Jaus
Ranch Hand
Posts: 342
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think it's a common situation that a spec says, something isn't allowed, but doesn't specify the system behavoir if someone does it anyhow. Now it's up to the provider how its implementation behaves.

In your case toplink decides to generate the table. Another persistence provider may decide to throw an exception. In order to create a portable application you shouldn't rely on the special behavoir of your provider.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic