• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 401
  • Last Modified:

Composite primary key with annotations

Hello,
So i have 2 EJB Entity class: Account and Contact.
An Account is linked to one (and only one) Contact, so the primary key of Account should be id and Contact but i dont know how to do.
I dont want to have a "int id_Contact" instead of my Contact class and i dont want to create a "AccountPK" class as i have seen on some java exemple web site!
My Account class is an Id and ,a Contact and an login. i dont want to change that by adding some dirty tricks.
Here my code:
@Entity
@Table(name="account")
public class Account implements Serializable{
	@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	@OneToOne(cascade={CascadeType.ALL})
	@JoinColumn(name="id_contact")
	private Contact contact;
	private String login;

Open in new window


@Entity
@Table(name="contact")
public class Contact implements Serializable {
         @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	private String name;

Open in new window

I have already tried by putting an annotation @Idclass above the class declaration and 2 @Id on the 2 parametes "id" and "Contact" but i have an error because "Contact" is not an idea (logical, its a Contact)
So how to do? i have looked at the  @JoinColumn to specify to use this column to create to Composite primary key...but no way apparently
I am using EJB 3.0 with native JAVA JPA (based on Hibernate) with JBOSS AS 7
Thanks
0
numtech
Asked:
numtech
  • 6
  • 4
1 Solution
 
for_yanCommented:

I think this ahows similar example for person - address in this link (look below the xml coding which is on top, but below they show it in annotations);
http://www.roseindia.net/jpa/eclipsejpaexamples/jparelationship/one-to-one.shtml
0
 
for_yanCommented:
This is basically one-to-one correspondence, so I think they show it in

@OneToOne annotaion on person field  within class Address

0
 
for_yanCommented:
This is another example:
http://en.wikibooks.org/wiki/Java_Persistence/OneToOne
Example of a OneToOne relationship annotations

@Entity
public class Employee {
  @Id
  @Column(name="EMP_ID")
  private long id;
  ...
  @OneToOne(fetch=FetchType.LAZY)
  @JoinColumn(name="ADDRESS_ID")
  private Address address;
  ...
}

Open in new window

0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
numtechAuthor Commented:
Its not just a one-ton-one relationship that i want. Because in youre example i can create 2 person with the same adress even if i put a OneToOne on the target table. Thats why i have to made a composite primary key, to prevent this.
Thus i dont want to modify the target table "Contact": A Contact dont have to know  "Account" table, more a i have other table that are linked to a contact.
So the problem is still not resolved, how to made a composite priamary key (for prevanting having 2 Account with the same Contact )
0
 
for_yanCommented:
Can't you specify Unique column for contact?
Because I guess you can have two contacts for account with one-to-one relationship between tables only if you have more than one row with the same contact?
Is there other way how it can happen?
0
 
numtechAuthor Commented:
I have tried:
@Column(unique=true)

Open in new window

but java told me :
@Column(s) not allowed on a @OneToOne property

for the moment i can do :
Contact cnt= new Contact("bob" ,"bob@mail.com")
createNewAccount(1 , Bob , cnt)
createNewAccount(2 , Alice , cnt)

Open in new window

But it dont want to allow that,it should throw an error because cnt is already linked with a Account. That's the role of a composite primary key.
0
 
for_yanCommented:
Then maybe you can get along withhout one-to-one property?
Just declare contact unique and have join column through id's?
would not that be enough?
0
 
numtechAuthor Commented:
mmh...Finnaly i have made work the first solution :
@IdClass(Account.class)
public Account implements Serializable{
        @Id @GeneratedValue
	private int id;
	@Id
	@OneToOne(cascade={CascadeType.ALL})
	@JoinColumn(name="id_contact")
	private Contact contact;

Open in new window


it create a primary key composed by both id and contact and now i cannot create 2 Account with the same Contact :)
My mistake was using:
@GeneratedValue(strategy=GenerationType.IDENTITY)

Open in new window

the "(strategy=GenerationType.IDENTITY)" created an error misunderstable!

So finnaly the "clean" solution worked perfectly! Thanks by the way, trying several option with you help me figure it out!
Cheers,


0
 
numtechAuthor Commented:
The best way to create a composite primary key with clean JPA annotation is by using this way
0
 
for_yanCommented:
Great,
Good it worked for you
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 6
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now