Wednesday, March 18, 2015

Retrieve Entity object with a embedded key

There are two types of objects.
Entity objects and value objects. Embedded key comes to action where value object / embedded object becomes a primary key for Entity object.

Eg : If we define two classes UserDetails.java - Entity and LoginName - value object/ embedded. Then we set LoginName as a primary key for UserDetail object.

So when we retrieve the UserDetail object from table via hibernate , (session.get.. ) , we have to provide the LoginName object as the serializable key to identify the raw data.

HibernateTest.java -  this class has the retrieve logic

----------------------------------------------------------------------------------------
import java.util.Date;

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

import dto.user.Address;
import dto.user.LoginName;
import dto.user.UserDetails;

public class HibernateTest {
public static void main(String[] args) {
UserDetails user = new UserDetails();
// user.setUserId(1);

LoginName loginName = new LoginName();
loginName.setFirstName("firstName");
loginName.setLastname("lastname");

user.setUserId(loginName);
user.setUserName("First User");
user.setJoinDate(new Date());
user.setDescription("FU description");

Address homeAddress = new Address();
homeAddress.setCity("hCity");
homeAddress.setPincode("hPincode");
homeAddress.setState("hstate");
homeAddress.setStreet("hstreet");

Address officeAddress = new Address();
officeAddress.setCity("oCity");
officeAddress.setPincode("oPincode");
officeAddress.setState("ostate");
officeAddress.setStreet("ostreet");

user.setHomeAddress(homeAddress);
user.setOfficeAddress(officeAddress);
// create session factory - one object- get session from SessionFactory
// need configuration to build sessionFactory
// new Configuration().configure()
// u need to have hibernate.cfg.xml in default place resources

SessionFactory sessionFactory = new Configuration().configure()
.buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
session.close();

// retrieve object
user = null;
session = sessionFactory.openSession();
session.beginTransaction();
user = (UserDetails) session.get(UserDetails.class, loginName);
System.out.println(user);
}
}



----------------------------------------------------------------------------------------


Other classes needed to test this application

UserDetails.java
----------------------------------------------------------------------------------------
package dto.user;

import java.util.Date;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Lob;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

@Entity
@Table(name = "USER_DETAILS")
public class UserDetails {

@EmbeddedId
private LoginName userId;
@Basic
private String userName;

@Temporal(TemporalType.TIMESTAMP)
private Date joinDate;
@Transient
private String notInTable;
@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_PINCODE")) })
private Address homeAddress;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "street", column = @Column(name = "OFFICE_STREET_NAME")),
@AttributeOverride(name = "city", column = @Column(name = "OFFICE_CITY_NAME")),
@AttributeOverride(name = "state", column = @Column(name = "OFFICE_STATE_NAME")),
@AttributeOverride(name = "pincode", column = @Column(name = "OFFICE_PINCODE")) })
private Address officeAddress;

@Lob
private String description;

public LoginName getUserId() {
return userId;
}

public void setUserId(LoginName userId) {
this.userId = userId;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public Date getJoinDate() {
return joinDate;
}

public void setJoinDate(Date joinDate) {
this.joinDate = joinDate;
}

public String getNotInTable() {
return notInTable;
}

public void setNotInTable(String notInTable) {
this.notInTable = notInTable;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public Address getHomeAddress() {
return homeAddress;
}

public void setHomeAddress(Address homeAddress) {
this.homeAddress = homeAddress;
}

public Address getOfficeAddress() {
return officeAddress;
}

public void setOfficeAddress(Address officeAddress) {
this.officeAddress = officeAddress;
}

@Override
public String toString() {
return "UserDetails [userId=" + userId + ", userName=" + userName
+ ", joinDate=" + joinDate + ", notInTable=" + notInTable
+ ", homeAddress=" + homeAddress + ", officeAddress="
+ officeAddress + ", description=" + description + "]";
}
}

----------------------------------------------------------------------------------------

LoginName.java
----------------------------------------------------------------------------------------
package dto.user;

import java.io.Serializable;

import javax.persistence.Embeddable;

@Embeddable
public class LoginName implements Serializable {

/**
*
*/
private static final long serialVersionUID = -121704761597041786L;
private String firstName;
private String lastname;

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastname() {
return lastname;
}

public void setLastname(String lastname) {
this.lastname = lastname;
}

@Override
public String toString() {
return "LoginName [firstName=" + firstName + ", lastname=" + lastname
+ "]";
}

}

----------------------------------------------------------------------------------------

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>
<property name="hibernate.bytecode.use_reflection_optimizer">false</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">root123</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test1</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>

<!-- drop and recreate databse on startup -->
<!-- <property name="hbm2ddl.auto">create</property> -->
<property name="hbm2ddl.auto">create</property>

<!-- dto classes annotated -->
<!-- previously <mapping resource="com/common/Stock.hbm.xml"></mapping> -->
<!-- if you do not have class the u have to comment -->
<!-- <mapping class="com.common.Stock"></mapping> -->
<mapping class="dto.user.UserDetails"></mapping>
</session-factory>
</hibernate-configuration>


------------------------------------------------------------------------------------------
Output of test class - HibernateTest.java
-------------------------------------------------------------------------------------------

INFO: HHH000227: Running hbm2ddl schema export
Hibernate: drop table if exists USER_DETAILS
Hibernate: create table USER_DETAILS (firstName varchar(255) not null, lastname varchar(255) not null, description longtext, HOME_CITY_NAME varchar(255), HOME_PINCODE varchar(255), HOME_STATE_NAME varchar(255), HOME_STREET_NAME varchar(255), joinDate datetime, OFFICE_CITY_NAME varchar(255), OFFICE_PINCODE varchar(255), OFFICE_STATE_NAME varchar(255), OFFICE_STREET_NAME varchar(255), userName varchar(255), primary key (firstName, lastname))
Mar 18, 2015 4:49:46 PM org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000230: Schema export complete
Hibernate: insert into USER_DETAILS (description, HOME_CITY_NAME, HOME_PINCODE, HOME_STATE_NAME, HOME_STREET_NAME, joinDate, OFFICE_CITY_NAME, OFFICE_PINCODE, OFFICE_STATE_NAME, OFFICE_STREET_NAME, userName, firstName, lastname) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: select userdetail0_.firstName as firstNam1_0_0_, userdetail0_.lastname as lastname2_0_0_, userdetail0_.description as descript3_0_0_, userdetail0_.HOME_CITY_NAME as HOME_CIT4_0_0_, userdetail0_.HOME_PINCODE as HOME_PIN5_0_0_, userdetail0_.HOME_STATE_NAME as HOME_STA6_0_0_, userdetail0_.HOME_STREET_NAME as HOME_STR7_0_0_, userdetail0_.joinDate as joinDate8_0_0_, userdetail0_.OFFICE_CITY_NAME as OFFICE_C9_0_0_, userdetail0_.OFFICE_PINCODE as OFFICE_10_0_0_, userdetail0_.OFFICE_STATE_NAME as OFFICE_11_0_0_, userdetail0_.OFFICE_STREET_NAME as OFFICE_12_0_0_, userdetail0_.userName as userNam13_0_0_ from USER_DETAILS userdetail0_ where userdetail0_.firstName=? and userdetail0_.lastname=?
UserDetails [userId=LoginName [firstName=firstName, lastname=lastname], userName=First User, joinDate=2015-03-18 16:49:44.0, notInTable=null, homeAddress=Address [street=hstreet, city=hCity, state=hstate, pincode=hPincode], officeAddress=Address [street=ostreet, city=oCity, state=ostate, pincode=oPincode], description=FU description]



------------------------------------------------------------------------------------------


Error which can come if you do not provide correct class object as key

let's give a String as key instead of object of LoginName.java

                session = sessionFactory.openSession();
session.beginTransaction();
user = (UserDetails) session.get(UserDetails.class, "firstName");
System.out.println(user);
-------------------------------------------------------------------------------------------

Exception in thread "main" org.hibernate.TypeMismatchException: Provided id of the wrong type for class dto.user.UserDetails. Expected: class dto.user.LoginName, got class java.lang.String
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:134)
at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1070)
at org.hibernate.internal.SessionImpl.access$2000(SessionImpl.java:176)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2551)
at org.hibernate.internal.SessionImpl.get(SessionImpl.java:955)
at HibernateTest.main(HibernateTest.java:56)



--------------------------------------------------------------------------------------------


Error in trying to retrieve using "NULL" value as key

session = sessionFactory.openSession();
session.beginTransaction();
loginName =null;
user = (UserDetails) session.get(UserDetails.class, loginName);
System.out.println(user);

Here I have set loginName =null;

------------------------------------------------------------------------------------------------
Exception in thread "main" java.lang.IllegalArgumentException: id to load is required for loading
at org.hibernate.event.spi.LoadEvent.(LoadEvent.java:109)
at org.hibernate.event.spi.LoadEvent.(LoadEvent.java:79)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2548)
at org.hibernate.internal.SessionImpl.get(SessionImpl.java:955)
at HibernateTest.main(HibernateTest.java:57)

------------------------------------------------------------------------------------------------

No comments:

Post a Comment