Now Suppose we have a requirement that we need to save a collection.
For example save all the address all the addresses where a user has lived,so this will have a collection of addresses.
Now in our example we will remove Address as attribute and add Set<Address> listOfAddresses to hold collection and remember to initialize it with HashSet() as below in our UserDetails.java.
@ElementCollection
To use collection in our class we have to annotate the attribute with @ElementCollection
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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
package com.technicalstack.dto; import java.util.HashSet; import java.util.Set; import javax.persistence.Column; import javax.persistence.ElementCollection; import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table (name="USER_DETAILS") public class UserDetails { @Id @GeneratedValue private int userId; @Column (name="USER_NAME") private String name; /*@Embedded private Address address; public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; }*/ @ElementCollection public Set<Address> listOfAddresses = new HashSet(); public Set<Address> getListOfAddresses() { return listOfAddresses; } public void setListOfAddresses(Set<Address> listOfAddresses) { this.listOfAddresses = listOfAddresses; } public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getName() { return name; } public void setName(String name) { this.name = name; } } |
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 39 40 41 42 |
package com.technicalstack.dto; import javax.persistence.GeneratedValue; import javax.persistence.Id; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateTest { public static void main(String[] args) { UserDetails user1 = new UserDetails(); // user1.setUserId(1); as we are using @Id @GeneratedValue so we don't need to set it. user1.setName("Shailesh"); Address add1 = new Address(); add1.setCity("Pune"); add1.setState("Maharashtra"); add1.setPincode("440011"); add1.setStreet("MG-Road"); user1.getListOfAddresses().add(add1); Address add2 = new Address(); add2.setCity("Mumbai"); add2.setState("Maharashtra"); add2.setPincode("440025"); add2.setStreet("Meera-Road"); user1.getListOfAddresses().add(add2); SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); Session session = sessionFactory.openSession(); session.beginTransaction(); session.save(user1); session.getTransaction().commit(); session.close(); } } |
Output:
1 2 3 4 5 6 7 8 9 10 11 12 |
Hibernate: drop table if exists UserDetails_listOfAddresses cascade Hibernate: drop sequence hibernate_sequence Hibernate: create sequence hibernate_sequence start 1 increment 1 Hibernate: create table USER_DETAILS (userId int4 not null, USER_NAME varchar(255), primary key (userId)) Hibernate: create table UserDetails_listOfAddresses (UserDetails_userId int4 not null, USER_CITY varchar(255), USER_PINCODE varchar(255), USER_STATE varchar(255), USER_STREET varchar(255)) Hibernate: alter table UserDetails_listOfAddresses add constraint FK6wx73ocb6j0mymo1jkcv0o3wm foreign key (UserDetails_userId) references USER_DETAILS Sep 25, 2016 8:23:00 AM org.hibernate.tool.hbm2ddl.SchemaExport execute INFO: HHH000230: Schema export complete Hibernate: select nextval ('hibernate_sequence') Hibernate: insert into USER_DETAILS (USER_NAME, userId) values (?, ?) Hibernate: insert into UserDetails_listOfAddresses (UserDetails_userId, USER_CITY, USER_PINCODE, USER_STATE, USER_STREET) values (?, ?, ?, ?, ?) Hibernate: insert into UserDetails_listOfAddresses (UserDetails_userId, USER_CITY, USER_PINCODE, USER_STATE, USER_STREET) values (?, ?, ?, ?, ?) |
Explanation:
At line 4 and 10,notice first hibernate has inserted in the table USER_DETAILS and then it created a new table UserDetails_listOfAddresses and has inserted UserDetails_userId as foreign key and has inserted the Address details in this table.
Entries in DataBase:
Next we will see use of annotation @JoinTable:
@JoinTable
Here we have seen that Hibernate has created the default table UserDetails_listOfAddresses which is not very friendly so now we will how to customize the name of the table created by Hibernate for the Addresses
We will have to use another annotation @JoinTable(name=”USER_ADDRESS”)
@ElementCollection
@JoinTable(name=”USER_ADDRESS“)
public Set<Address> listOfAddresses = new HashSet();
Now when you rerun the application you will find hibernate has created the USER_ADDRESS table and has inserted the records in it.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Hibernate: drop table if exists USER_ADDRESS cascade Hibernate: drop table if exists USER_DETAILS cascade Hibernate: drop sequence hibernate_sequence Hibernate: create sequence hibernate_sequence start 1 increment 1 Hibernate: create table USER_ADDRESS (UserDetails_userId int4 not null, USER_CITY varchar(255), USER_PINCODE varchar(255), USER_STATE varchar(255), USER_STREET varchar(255)) Hibernate: create table USER_DETAILS (userId int4 not null, USER_NAME varchar(255), primary key (userId)) Hibernate: alter table USER_ADDRESS add constraint FK30p76h3gg2si436waw9bt9e9n foreign key (UserDetails_userId) references USER_DETAILS Sep 25, 2016 9:21:40 AM org.hibernate.tool.hbm2ddl.SchemaExport execute INFO: HHH000230: Schema export complete Hibernate: select nextval ('hibernate_sequence') Hibernate: insert into USER_DETAILS (USER_NAME, userId) values (?, ?) Hibernate: insert into USER_ADDRESS (UserDetails_userId, USER_CITY, USER_PINCODE, USER_STATE, USER_STREET) values (?, ?, ?, ?, ?) Hibernate: insert into USER_ADDRESS (UserDetails_userId, USER_CITY, USER_PINCODE, USER_STATE, USER_STREET) values (?, ?, ?, ?, ?) |
@JoinColumn
here if you notice even in the generated new table the primary key the default UserDetails_userId which is again needs to be customised. So lets see how to do that.
@ElementCollection
@JoinTable(name=”USER_ADDRESS“,joinColumns=@JoinColumn(name=”USER_ID“))
)
public Set<Address> listOfAddresses = new HashSet();
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Hibernate: drop table if exists USER_ADDRESS cascade Hibernate: drop table if exists USER_DETAILS cascade Hibernate: drop sequence hibernate_sequence Hibernate: create sequence hibernate_sequence start 1 increment 1 Hibernate: create table USER_ADDRESS (USER_ID int4 not null, USER_CITY varchar(255), USER_PINCODE varchar(255), USER_STATE varchar(255), USER_STREET varchar(255)) Hibernate: create table USER_DETAILS (userId int4 not null, USER_NAME varchar(255), primary key (userId)) Hibernate: alter table USER_ADDRESS add constraint FK3ndjyd9yl6efpjb7jx0voo2yk foreign key (USER_ID) references USER_DETAILS Sep 25, 2016 9:56:58 AM org.hibernate.tool.hbm2ddl.SchemaExport execute INFO: HHH000230: Schema export complete Hibernate: select nextval ('hibernate_sequence') Hibernate: insert into USER_DETAILS (USER_NAME, userId) values (?, ?) Hibernate: insert into USER_ADDRESS (USER_ID, USER_CITY, USER_PINCODE, USER_STATE, USER_STREET) values (?, ?, ?, ?, ?) Hibernate: insert into USER_ADDRESS (USER_ID, USER_CITY, USER_PINCODE, USER_STATE, USER_STREET) values (?, ?, ?, ?, ?) |