dineshonjava

Collections in Hibernate and Adding Keys Example

In previous tutorial of Collections in Hibernate and Adding Keys Example we wrote the collection of objects of an entity class, we persist in the separate table, here there are following two tables are created in the database.

1. TBL_USER_DETAILS for UserDetails entity type object
2. TBL_USER_DETAILS_lisOfAddresses  for Address value type object

In this chapter we will explore some advanced options about the collection.
Now we see first thing is the name of the table.

TBL_USER_DETAILS_lisOfAddresses is name for the collection table it is not very user friendly name.

To overcome this problem we will use annotation @JoinTable.
 @JoinTable:
 Target:
             Fields (including property get methods)

  Used in the mapping of associations. It is specified on the owning side of an association.
A join table is typically used in the mapping of many-to-many and unidirectional one-to-many associations. It may also be used to map bidirectional many-to-one/one-to-many associations, unidirectional many-to-one relationships, and one-to-one associations (both bidirectional and unidirectional).

When a join table is used in mapping a relationship with an embeddable class on the owning side of the relationship, the containing entity rather than the embeddable class is considered the owner of the relationship.

If the JoinTable annotation is missing, the default values of the annotation elements apply. The name of the join table is assumed to be the table names of the associated primary tables concatenated together (owning side first) using an underscore.

@Entity
@Table (name="USERS_DETAILS")

public class UserDetails
{
    @Id
    @Column(name="USER_ID")
    @GeneratedValue(strategy=GenerationType.AUTO)

    private int    userId;
   
    @Column(name="USER_NAME")

    private String userName;
   
    @ElementCollection
    @JoinTable(name="USER_ADDRESS")
//name of the table is changed to USER_ADDRESS
    private Collection<Address> lisOfAddresses = new ArrayList<Address>();
}

Collections in Hibernate Example

After running the above code the following output string show the updated table name of the collection table.

Now we see that the name of the column of this table which have the foreign key user id is the USER_DETAILS_USER_ID is not also very user friendly, for this look to the following updated code of the UserDetails entity class. Here we used annotation @JoinColumn.
@JoinColumn
Target:
Fields (including property get methods)
Specifies a column for joining an entity association or element collection. If the JoinColumn annotation itself is defaulted, a single join column is assumed and the default values apply.

@JoinColumns:
Target:
Fields (including property get methods)
Defines mapping for composite foreign keys. This annotation groups JoinColumn annotations for the same relationship. When the JoinColumns annotation is used, both the name and the referencedColumnName elements must be specified in each such JoinColumn annotation.

@Entity
@Table (name="USERS_DETAILS")

public class UserDetails
{
    @Id
    @Column(name="USER_ID")
    @GeneratedValue(strategy=GenerationType.AUTO)

    private int    userId;
   
    @Column(name="USER_NAME")

    private String userName;
   
    @ElementCollection
    @JoinTable(name="USER_ADDRESS",
            joinColumns=@JoinColumn(name="USER_ID"))

    private Collection<Address> lisOfAddresses = new ArrayList<Address>();
}

Look the following snap of the output..

Collections in Hibernate and Adding Keys Example

Now we look for how to adding key to the collection table.

UserDetails.java
package com.sdnext.hibernate.tutorial.dto;

import java.util.ArrayList;
import java.util.Collection;

import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Table;

import org.hibernate.annotations.CollectionId;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Type;

@Entity
@Table (name="USER_DETAIL")

public class UserDetails
{
    @Id
    @Column(name="USER_ID")
    @GeneratedValue(strategy=GenerationType.AUTO)

    private int    userId;
  
    @Column(name="USER_NAME")
    private String userName;
  
    @ElementCollection
    @JoinTable(name="USER_ADDRESS",
            joinColumns=@JoinColumn(name="USER_ID"))
    @GenericGenerator(strategy="hilo", name = "hilo-gen")
    @CollectionId(columns = { @Column(name="ADDRESS_ID") }, generator = "hilo-gen", type = @Type(type="long"))

    private Collection<Address> lisOfAddresses = new ArrayList<Address>();
  
    public Collection<Address> getLisOfAddresses() {
        return lisOfAddresses;
    }
    public void setLisOfAddresses(Collection<Address> lisOfAddresses) {
        this.lisOfAddresses = lisOfAddresses;
    }
    public int getUserId() {
        return userId;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String toString()
    {
        return "[User Name: "+userName+"\n Office Address: "+lisOfAddresses+"]";
    }
}

Address.java and hibernate.cfg.xml is the same as previous chapter.


HibernateTestDemo.java

package com.sdnext.hibernate.tutorial;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

import com.sdnext.hibernate.tutorial.dto.Address;
import com.sdnext.hibernate.tutorial.dto.UserDetails;

public class HibernateTestDemo {
    /**
     * @param args
     */
    public static void main(String[] args)
    {
        UserDetails user = new UserDetails();
        //user.setUserId(1);
        user.setUserName("Dinesh Rajput");
       
        Address address1 = new Address();
        address1.setStreet("First Street");
        address1.setCity("First City");
        address1.setState("First State");
        address1.setPincode("First Pin");
       
        Address address2 = new Address();
        address2.setStreet("Second Street");
        address2.setCity("Second City");
        address2.setState("Second State");
        address2.setPincode("Second Pin");
       
        user.getLisOfAddresses().add(address1);
        user.getLisOfAddresses().add(address2);
       
        SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        session.save(user);
        session.getTransaction().commit();
        session.close();
    }
}
Output: 
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
log4j:WARN Please initialize the log4j system properly.
Hibernate: insert into USER_DETAIL (USER_NAME) values (?)
Hibernate: insert into USER_ADDRESS (USER_ID, ADDRESS_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into USER_ADDRESS (USER_ID, ADDRESS_ID, CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME) values (?, ?, ?, ?, ?, ?)

Collections in Hibernate example output


Tables:

example output
In Next Chapter we will see about that Proxy Object and Fetching strategies.

                                  <<Previous Chapter 14<<    >>Next Chapter16