Implementing composite key is different from the normal primary key , which I have explained in my previous post How to implement primary key with JPA and Hibernate .In this example we are going to learn how to create a compound primary key.
Here let’s take an example table ACCOUNT with three attributes
[Emp_id]
[Account_id]
[Balance].
imagine a situation where we need a combination of Emp_id and Account_id to make up our prmary key.
For this , we will create a separate class with the attributes with which we want to create a compound key ie, Emp_id and Account_id
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
import java.io.Serializable; import javax.persistence.Embeddable; @Embeddable public class CompoundKey implements Serializable{ private String emp_id; private String account_id; public CompoundKey(String emp_id,String account_id) { this.emp_id=emp_id; this.account_id=account_id; } public String getAccount_id() { return account_id; } public void setAccount_id(String account_id) { this.account_id = account_id; } public String getEmp_id() { return emp_id; } public void setEmp_id(String emp_id) { this.emp_id = emp_id; } } |
The above compound key class need special implementation
1) The compound key class must implement serializable interface.
2) Annotate the class with embeddable.
3) All the getters and setters.
4) You can create the constructor, Which is not mandatory.
Now let’s create the class for Object relational mapping. Instead of getter/setter methods of the three data , we will create one object for the compound key class and the other attribute Balance.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table @Entity @Table(name="ACCOUNT") public class AccountVO { private CompoundKey compoundKey; private int balance; @Id public CompoundKey getCompoundKey() { return compoundKey; } public void setCompoundKey(CompoundKey compoundKey) { this.compoundKey = compoundKey; } @Column(name="Balance") public int getBalance() { return balance; } public void setBalance(int balance) { this.balance = balance; } } |
Here you can notice that we have used @Id – for creating id we have created the object of the class CompoundKey
Hibernate Client code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
package compoundPrimarykey; import java.util.Iterator; import java.util.List; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.AnnotationConfiguration; public class testHibernate { public static void main(String[] args) { AnnotationConfiguration config=new AnnotationConfiguration(); config.addAnnotatedClass(AccountVO.class); config.addAnnotatedClass(CompoundKey.class); SessionFactory sessionFactory = config.configure().buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction tx=session.beginTransaction(); CompoundKey compoundKey=new CompoundKey("100848","100"); AccountVO accountVO=new AccountVO(); accountVO.setCompoundKey(compoundKey); accountVO.setBalance(100000); session.save(accountVO); Criteria crt=session.createCriteria(AccountVO.class); List list=crt.list(); for (Iterator ite = list.iterator(); ite.hasNext();) { AccountVO accountVO2= (AccountVO) ite.next(); System.out.println("Account Balance ="+accountVO2.getBalance()); CompoundKey compoundKey2=accountVO2.getCompoundKey(); System.out.println("Emp id ="+compoundKey2.getEmp_id()); System.out.println("Account id ="+compoundKey2.getAccount_id()); } tx.commit(); } } |
Sumit says
February 10, 2011 at 5:21 pmIs this entity getting updated as well?
Using a similar configuration, I am able to save into the database, but am unable to update it.
bkrakesh says
February 10, 2011 at 6:17 pmYou can do update also using the same way explained in the example . Please try this code
String updateBalanceQuery=”update AccountVO accountvo set accountvo.balance=500 where accountvo.compoundKey.emp_id=:empID”;
Query query=session.createQuery(updateBalanceQuery);
query.setString(“empID”, “100848”);
query.executeUpdate();
Talia Frump says
May 28, 2011 at 6:15 pmThank you, I have recently been searching for information about this topic for ages and yours is the best I have discovered so far.
Vernell Valdovino says
May 29, 2011 at 9:53 pmGreat information! I’ve been looking for something like this for a while now. Thanks!
Kenya Nevarrez says
May 29, 2011 at 10:03 pmThis is such a great resource that you are providing and you give it away for free. I enjoy seeing websites that understand the value of providing a prime resource for free. I truly loved reading your post. Thanks!
Chen Bo says
July 19, 2011 at 3:26 pmThank you for the post. It works.
However, I have a question about the annotation mapping.
In class AccountVO balance field, we have annotation @Column(name=”Balance”) to clearly map balance to the corresponding table column. However, for the CompoundKey, we do not have similar annotations for the compound key fields. How does Hibernate know which column in the database table to map the key fields to?
Thanks.
dhanasekhar says
July 26, 2011 at 3:36 pmI want to put @GeneratedValue for one of id, please explain the scenario
Ali says
February 6, 2012 at 3:02 pmThanks dude!!!
Great and Simple tutotial…
Many Thanks,
Ali
chandra says
March 13, 2012 at 9:30 amGreat……i understood abt wt u have implemented but wt my question is how to implement auto increment for composite key.
Thanks
chandra
Mansoor says
March 25, 2012 at 8:18 pmThanks
Sunil says
June 20, 2012 at 4:20 amwhat happens if you are creating the account or employee. the composite key wouldn’t have the account id available at that time, right? how does that work?
Best of Android says
August 7, 2012 at 5:55 pmThank you very much for sharing this code. It helped me in solving the issue 🙂
Tomek says
November 28, 2012 at 2:54 pmThank you, this helped. 🙂
Peter Sarazin says
December 28, 2012 at 3:51 amThis got me 90% of the way in my application. My class attribute names do not match my database column names, so to make it fully work I just had to add @Column annotations to my equivalent of the emp_id and account_id attributes in the CompoundKey class implementation.
totanagouda says
December 11, 2014 at 10:22 amgood post