I am trying to create a simple example to understand how collection of basic and embaddable types works in Hibernate.
I have created a User
entity with a set of nickNames
and also a set of addresses
. Here are my Java classes:
User.java
@Entity
@Table(name = "TB_User")
public class User {
@Id
@GeneratedValue
private int id;
private String name;
@ElementCollection
@CollectionTable(name = "Nicknames", joinColumns = @JoinColumn(name = "user_id"))
@Column(name = "nickname")
private Set<String> nickNames = new HashSet<String>();
@ElementCollection
@CollectionTable(name = "Addresses", joinColumns = @JoinColumn(name = "user_id"))
@AttributeOverrides({ @AttributeOverride(name = "street1", column = @Column(name = "fld_street")) })
public Set<Address> addresses = new HashSet<Address>();
public User() {
}
public User(String name, Address... addresses) {
this.name = name;
this.addresses.addAll(Arrays.asList(addresses));
}
public void addNickName(String... nickNames) {
this.nickNames.addAll(Arrays.asList(nickNames));
}
// Setters & Getters
}
Address.java
@Embeddable
public class Address {
private String street1;
public Address() {}
public Address(String street1) {
this.street1 = street1;
}
@Override
public String toString() {
return street1;
}
// Setters & Getters
}
Now I have created a simple program to create users in database and then show the list of users. Here is my code:
private static void saveUsers() {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.getTransaction().begin();
User user = new User("User", new Address("abc"),
new Address("xyz"));
user1.addNickName("alpha", "beta");
session.save(user);
session.getTransaction().commit();
}
private static void showUsers() {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.getTransaction().begin();
List<User> users = session.createQuery("from User").list();
for (User user : users) {
System.out.println(user.getName() + " -- > " + user.getNickNames()
+ " --> " + user.getAddresses());
}
session.getTransaction().commit();
}
When I run this program, I observed that hibernate issues below set of commands:
Hibernate: select user0_.id as id1_2_, user0_.name as name2_2_ from TB_User user0_
Hibernate: select nicknames0_.user_id as user_id1_2_0_, nicknames0_.nickname as nickname2_1_0_ from Nicknames nicknames0_ where nicknames0_.user_id=?
Hibernate: select addresses0_.user_id as user_id1_2_0_, addresses0_.fld_street as fld_street2_0_0_ from Addresses addresses0_ where addresses0_.user_id=?
User -- > [alpha, beta] --> [xyz, abc]
Hibernate: delete from Addresses where user_id=?
Hibernate: insert into Addresses (user_id, fld_street) values (?, ?)
Hibernate: delete from Addresses where user_id=?
Hibernate: insert into Addresses (user_id, fld_street) values (?, ?)
If I try to get the list of addresses using user.getAddresses()
with in session
, then Hibernate deletes & re-inserts records in Addresses
table.
Why hibernate tries to delete and re-create records in Addresses
table, as this causes performance issue. Also why it is not applicable to basic types like nickNames
in my example and not running update commands for the property nickNames
?