We’ll learn the difference between Entity type objects and Value type objects. We’ll use the @Embeddable annotations to embed a value type object into our Entity class.
"An object of value type has no database identity; it belongs to an entity instance and its persistent state is embedded in the table row of the owning entity. Value types don't have identifiers or identifier properties"
Now In short we look the following points...
Object of Entity Type : has its own database identity
Object of Value Type : belongs to an entity, and its persistent state is embedded in the table row
of the owning entity. Value types don't have identifiers or identifier properties.
We look following example of Object of Entity Type: @Entity
@Table(name="USER_TABLE") public class UserDetails{
@Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="USER_ID", type="INTEGER")
private long userId;
@Column(name="USER_NAME", type="String") private String userName;
@Column(name=USER_ADDRESS, type="String") private String address;
@Column(name="USER_PHONE", type="INTEGER") private long phone;
@Column(name="DOB", type="TIMESTAMP") private Date dob;
}
In Above table we saw that type of the all fields of the class USER CLASS have database entity type object.
ID is INTEGER type Name is VARCHAR type ADDRESS is VARCHAR type Phone is BIG INTEGER type DOB is TIMESTAMP type
All are the Entity Type Objects.
@Entity
@Table(name="USER_TABLE") public class UserDetails{
@Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="USER_ID", type="INTEGER")
private long userId;
@Column(name="USER_NAME", type="String") private String userName;
@Column(name=USER_ADDRESS, type="??????") //What should be type for database private Address address;
@Column(name="USER_PHONE", type="INTEGER") private long phone;
@Column(name="DOB", type="TIMESTAMP") private Date dob;
}
Now lets see table structure for that...
here USER CLASS have a field Address type of the Value type object means in the database there are no meaning of Address type object.
Address type object have the four other fields like. 1. Street
3. State 4. Pin code
VALUE TYPE OBJECT APPROACH:>
Here there are one approach to save the value the Address Object save to the USER TABLE is the save the individually fields of this object to the separate columns of the USER TABLE. As following
This scenario is working in the hibernate only one condition is Address Object should be a Value Object (means there is no meaning to itself its provide the meaning to the entity object).
In this approach there are some problems are 1. Table complexity
2. Data Redundancy
3. User may have multiple Address like home address and office address etc. Look the above example in the code...
Address.java
package com.sdnext.hibernate.tutorial.dto; import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable //for value object it is not is entity object. Value object means does not have real
public class Address {
@Column(name="STREET_NAME") private String street;
@Column(name="CITY_NAME") private String city;
@Column(name="STATE_NAME") private String state;
@Column(name="PIN_CODE") private String pincode;
public String getStreet() { return street;
}
public void setStreet(String street) { this.street = street;
}
public String getCity() { return city;
}
public void setCity(String city) { this.city = city;
}
public String getState() { return state;
}
public void setState(String state) { this.state = state;
}
public String getPincode() { return pincode;
}
public void setPincode(String pincode) { this.pincode = pincode;
}
public String toString() {
return " {Street: "+street+" City: "+city+" State: "+state+" Pincode: "+pincode+" }"; }
}
@Embeddable: Target:
Classes
Defines a class whose instances are stored as an intrinsic part of an owning entity and share the identity of the entity. Each of the persistent properties or fields of the embedded object is mapped to the database table for the entity.
UserDetails.java package com.sdnext.hibernate.tutorial.dto; import java.util.Date; import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.Entity;
import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table (name="USER_TABLE") public class UserDetails
{
@Id @GeneratedValue(strategy=GenerationType.AUTO) @Column(name="USER_ID")
private int userId;
@Column(name="USER_NAME") private String userName;
@Embedded //For value type object private Address address;
@Column(name="USER_PHONE") private String phone;
@Column(name="DOB") private Date dob;
public void setUserId(int userId) { this.userId = userId;
}
public String getUserName() { return userName;
}
public void setUserName(String userName) { this.userName = userName;
}
public Address getAddress() { return address;
}
public void setAddress(Address address) { this.address = address;
}
public String getPhone() { return phone;
}
public void setPhone(String phone) { this.phone = phone;
}
public Date getDob() { return dob;
}
public void setDob(Date dob) { this.dob = dob;
}
public int getUserId() { return userId; }
{
return "[User Name: "+userName+"User Id: "+userId+" User Address "+address+" Use phone " +phone+" ]";
} }
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateDB</property> <property name="connection.username">root</property>
<property name="connection.password">root</property> <!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property> <!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> <!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">create</property> <mapping class="com.sdnext.hibernate.tutorial.dto.UserDetails"/> </session-factory> </hibernate-configuration> HibernateTestDemo.java package com.sdnext.hibernate.tutorial; import java.util.Date; 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 user1 = new UserDetails(); //create first user UserDetails user2 = new UserDetails(); //create second user
user1.setUserName("Dinesh Rajput"); user2.setUserName("Anamika Rajput");
Address address1 = new Address(); //create first value type object for entity type object user1 address1.setStreet("K Block House No. 403");
address1.setCity("Mangol Puri"); address1.setState("New Delhi"); address1.setPincode("110083"); user1.setAddress(address1);
Address address2 = new Address();//create second value type object for entity type object user2 address2.setStreet("Film City"); address2.setCity("Noida"); address2.setState("UP"); address2.setPincode("201301"); user2.setAddress(address2); user1.setDob(new Date()); user1.setPhone("+91-9953423462"); user2.setDob(new Date()); user2.setPhone("+91-9973423462");
SessionFactory sessionFactory = new
AnnotationConfiguration().configure().buildSessionFactory(); //create a session factory object Session session = sessionFactory.openSession(); // create session object from session factory session.beginTransaction(); //begin transaction for this session
session.save(user1); //save the first user session.save(user2); //save the second user
session.getTransaction().commit(); //commit the transaction the session session.close(); //close the session
} }
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_TABLE (CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME, DOB, USER_PHONE, USER_NAME) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into USER_TABLE (CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME, DOB, USER_PHONE, USER_NAME) values (?, ?, ?, ?, ?, ?, ?)
Attributes Override:
Here we have seen that an Entity Type Object USER has a Value Type Object(or Embeddable Object ) ADDRESS with corresponding fields name street, city, pin-code and state save to the database table USER_TABLE with value type object's column name (CITY_NAME, PIN_CODE, STATE_NAME, STREET_NAME).
But here some problems, suppose this user object have two types of addresses as like Local Address and Permanent Address then how to manage the column names of these value type objects in the database table USER_TABLE.
To overcome this problem we have to override the Attributes of the Value type objects. Lets see how to get in the code...
UserDetails.java package com.sdnext.hibernate.tutorial.dto; import java.util.Date; import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Lob; import javax.persistence.Table; @Entity
@Table (name="USER_TABLE")public class UserDetails {
@Id
@Column(name="USER_ID")
@GeneratedValue(strategy=GenerationType.AUTO) private int userId;
private String userName;
@Column(name="DOB") private Date joinDate; @Column(name="ADDRESS") @Embedded @AttributeOverrides({ @AttributeOverride(name="street", column=@Column(name="HOME_STREET_NAME")), @AttributeOverride(name="city", column=@Column(name="HOME_CITY_NAME")), @AttributeOverride(name="state", column=@Column(name="HOME_STATE_NAME")), @AttributeOverride(name="pincode", column=@Column(name="HOME_PIN_CODE"))}) private Address homeAddress;
@Embedded
private Address permanentAddress;
@Column(name="Phone") private String phone;
public int getUserId() { return userId; }
public Address getHomeAddress() { return homeAddress;
}
public void setHomeAddress(Address homeAddress) { this.homeAddress = homeAddress;
}
public void setUserId(int userId) { this.userId = userId;
}
public String getUserName() { return userName;
}
public void setUserName(String userName) { this.userName = userName;
}
public Date getDob() { return dob;
}
public void setDob(Date dob) { this.dob= dob;
}
public Address getPermanentAddress() { return permanentAaddress;
}
public void setPermanentAddress(Address permanentAddress) { this.permanentAddress = permanentAddress;
}
public String getPhone() { return phone;
}
public void setPhone(String phone) { this.phone= phone;
public String toString() {
return "[User Name: "+userName+"\n Permanent Address: "+permanentAddress+"\n Home Address: "+homeAddress+"\n Date of Birth: "+dob+"\n Phone: "+phone+"]";
} }
Now run the following code of the class file.. HibernateTestDemo.java package com.sdnext.hibernate.tutorial; import java.util.Date; 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(); //create an user is entity type object //user.setUserId(1);
user.setUserName("Dinesh Rajput");
Address address = new Address(); //create an value type object of address class for home address address.setStreet("Block House No");
address.setCity("MangolaPuri"); address.setState("New Delhi"); address.setPincode("110089");
user.setHomeAddress(address); //set the home address
Address address1 = new Address();//create another value type object for the permanent address address1.setStreet("Film City");
address1.setCity("Noida"); address1.setState("UP"); address1.setPincode("201301");
user.setPermanentAddress(address1);//set the permanent address
user.setDob(new Date()); user.setPhone("9999222211");
SessionFactory sessionFactory = new
AnnotationConfiguration().configure().buildSessionFactory(); //create a session factory object Session session = sessionFactory.openSession(); //create a session object
session.beginTransaction(); //transaction object start
session.getTransaction().commit(); //commit the transaction object session.close(); //close the session
} }
After running the above code we will get the following table structure...