Hibernate Student Handout. Software required. Eclipse Europa. HSQL Database. Exercise 1 a Step 1. Jar files required for the simple Hibernate application.Add to the build path. cglib-nodep-2.1_3.jar commons-collection.jar commons-logging.jar dom4j-1.6.1.jar hibernate3.jar hsqldb.jar jta.jar Step 2. The sample programs are executed in HSQL Server .Create a sample database called mydb.xdb is the alias name. java cp ../lib/hsqldb.jar org.hsqldb.Server database.0 mydb dbname.0 xdb
Make sure u have hsqldb.jar. Type the above in the command line. This creates a database named xdb. java -cp hsqldb.jar org.hsqldb.util.DatabaseManager The above command runs a tool,so that u can view you files. Database Tool. Select HSQL Database Engine Server. Write the following URL. jdbc:hsqldb:hsql://localhost:9001/xdb Leave the other columns as is. Step 3. Create a Java Project using Eclipse. To the source folder, add the following 3 java files. HibernateUtil.java import org.hibernate.*; import org.hibernate.cfg.*; public class HibernateUtil {
public static final SessionFactory sessionFactory; static { try { // Create the SessionFactory from hibernate.cfg.xml sessionFactory = new Configuration().configure().buildSessionFactory(); } catch (Throwable ex) { // Make sure you log the exception, as it might be swallowed System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public static final ThreadLocal session = new ThreadLocal(); public static Session currentSession() throws HibernateException { Session s = (Session) session.get(); // Open a new Session, if this thread has none yet if (s == null) { s = sessionFactory.openSession(); // Store it in the ThreadLocal variable session.set(s); } return s; } public static void closeSession() throws HibernateException { Session s = (Session) session.get(); if (s != null) s.close(); session.set(null); } } EventManager.java import org.hibernate.Transaction; import org.hibernate.Session;
public class EventManager { public static void main(String[] args){
Session session = HibernateUtil.currentSession(); Transaction tx = session.beginTransaction(); Person theperson = new Person(); theperson.setAge(10); theperson.setFirstname("Susithra"); theperson.setLastname("Chandrabose"); session.save(theperson); tx.commit(); System.out.println("Person is stored"); HibernateUtil.closeSession(); HibernateUtil.sessionFactory.close(); } } Person.java import java.util.*; public class Person { private private private private
Long id; int age; String firstname; String lastname;
Person() {} public Long getId() { return id; } private void setId(Long id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } 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; }
}
Add the following xml files to the Java Class Path. hibernate.cfg.xml <session-factory> <property name="connection.driver_class">org.hsqldb.jdbcDriver <property name="connection.url">jdbc:hsqldb:hsql://localhost:9001/xdb <property name="connection.username">sa <property name="connection.password"> <property name="connection.pool_size">10 <property name="dialect">org.hibernate.dialect.HSQLDialect <property name="show_sql">true <property name="hbm2ddl.auto">create <mapping resource="Person.hbm.xml"/>
Person.hbm.xml
<property name="age"/> <property name="firstname"/> <property name="lastname"/>
Run the application. Check the database PERSON table is created . Now we have successfully created a table. We will add few more rows to it. Comment on the following line
Add different persons. Run the application and check the database.
Hibernate object states Hibernate defines and supports the following object states: •
•
•
Transient - an object is transient if it has just been instantiated using the new operator, and it is not associated with a Hibernate Session. It has no persistent representation in the database and no identifier value has been assigned. Transient instances will be destroyed by the garbage collector if the application doesn't hold a reference anymore. Use the Hibernate Session to make an object persistent (and let Hibernate take care of the SQL statements that need to be executed for this transition). Persistent - a persistent instance has a representation in the database and an identifier value. It might just have been saved or loaded, however, it is by definition in the scope of a Session. Hibernate will detect any changes made to an object in persistent state and synchronize the state with the database when the unit of work completes. Developers don't execute manual UPDATE statements, or DELETE statements when an object should be made transient. Detached - a detached instance is an object that has been persistent, but its Session has been closed. The reference to the object is still valid, of course, and the detached instance might even be modified in this state. A detached instance can be reattached to a new Session at a later point in time, making it (and all the modifications) persistent again. This feature enables a programming model for long running units of work that require
user think-time. We call them application transactions, i.e. a unit of work from the point of view of the user. The first application what we have seen we used Persistent objects. To Load an Object Modify the EventManager as follows import org.hibernate.Transaction; import org.hibernate.Session; public class EventManager { public static void main(String[] args){ Session session = HibernateUtil.currentSession(); Transaction tx = session.beginTransaction(); Person theperson = new Person(); theperson.setAge(30); theperson.setFirstname("Subbu"); theperson.setLastname("David"); session.save(theperson); tx.commit(); //Loading an Object Person person=new Person(); session.load(person, new Long(1)); System.out.println("Person loaded from the database"); System.out.println("Name"+person.getFirstname()); HibernateUtil.closeSession(); HibernateUtil.sessionFactory.close(); } } Run the application to see the output on the console. It throws exception if the matching Person is not there in the database .If you are not sure then use the get() method. Person person=new Person();
person=(Person) session.get(Person.class, new Long(1)); System.out.println("Person loaded from the database"); System.out.println("Name"+person.getFirstname());
Exercise 1 b Querying(HQL) Add the following lines inside the active session to list all the persons using createQuery List persons = session.createQuery("from Person as person").list(); Iterator i= persons.iterator(); while(i.hasNext()){ System.out.println(" "+i.next()); }
Override String toString() method in the Person class. To add where clause type the following List persons2 = session.createQuery( "from Person as person where person.lastname = ?") .setString(0, "Chandrabose") .list(); Iterator i2= persons2.iterator(); while(i2.hasNext()){ System.out.println("person2"+i2.next()); } Lastname corresponds to the private member of the Person class.
Exercise for students You can set all other datatypes using setXXX methods and also setEntity. Practise all this in the same program. You can get a unique list using Set. Query query = session.createQuery("select person.firstname from Person as person"); Set person3=new HashSet(query.list()); Iterator i3= person3.iterator(); while(i3.hasNext()){ System.out.println(" "+i3.next()); }
Queries may specify a property of a class in the select clause. They may even call SQL aggregate functions. Properties or aggregates are considered "scalar" results (and not entities in persistent state). Exercise for students Implement any aggregate functions.
Modifying persistence objects can be done by calling the flush method no need to call update .It is taken by the hibernate automatically. Person person=new Person(); person=(Person) session.get(Person.class, new Long(1)); System.out.println("Person loaded from the database"); System.out.println("Name"+person.getFirstname()); person.setFirstname("Accenture"); session.flush(); tx.commit();
Modifying detached objects can be done by calling the update method. Session session2 = HibernateUtil.currentSession(); Transaction tx2 = session2.beginTransaction(); person.setFirstname("Susithra"); session2.update(person); tx2.commit(); HibernateUtil.closeSession();
Automatic State Detection. If u are sure of the state use saveOrUpdate() method. Deleting persistent objects session2.delete(person);
Exercise 2 a Relationships. One to One associations two varieties .Primary key association as well as unique foreign key associations .The following example shows One to One association (Unique foreign key associations) One person can have an address .The Address is a member of Person class. Address.java package com.accenture.domain;
public class Address { private Long id; private String city; private String country; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getCity() { return city; } public void setCity(String city) { this.city = city; }
public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } }
Person.java package com.accenture.domain; public class Person { private Long id; private String name; private Address address = new Address(); public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Person.hbm.xml
<property name="name" column="PERSONNAME" type="java.lang.String" /> <many-to-one name="address" column="addressId" not-null="true" lazy="false" unique="true"/> <property name="city" column="CITY" type="java.lang.String" />
<property name="country" column="COUNTRY" type="java.lang.String" />
create table Person ( personId bigint not null primary key, addressId bigint not null unique ) create table Address ( addressId bigint not null primary key )
The mapping file remains the same. But except give the complete path <mapping resource="com/accenture/domain/Person.hbm.xml"/> package com.accenture.client; import org.hibernate.Session; import org.hibernate.Transaction; import com.accenture.Utilities.HibernateUtil; import com.accenture.domain.Address; import com.accenture.domain.Person;
public class EventManager { public static void main(String[] args){ Session session = HibernateUtil.currentSession(); Transaction tx = session.beginTransaction(); Address address=new Address(); address.setCity("Bangalore"); address.setCountry("India"); session.save(address); Person theperson = new Person(); theperson.setName("Susithra C"); theperson.setAddress(address); session.save(theperson); tx.commit(); HibernateUtil.closeSession(); HibernateUtil.sessionFactory.close(); }}
Exercise 2 b One to Many association (Bi Directional) Child.java package com.accenture.domain; public class Child { private Long id; private String name; private Parent parent; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) {
}
this.name = name;
public Parent getParent() { return parent; } public void setParent(Parent parent) { this.parent = parent; } }
Parent.java package com.accenture.domain; import java.util.HashSet; import java.util.Set; public class Parent { private Long id; private String name; private Set children = new HashSet(); public Set getChildren() { return children; } public void setChildren(Set children) { this.children = children; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Parent.hbm.xml
<property name="name"/> <set name="children" table="ParentChild" cascade="all" inverse="true" lazy="false"> <many-to-many column="child_id" class="Child"/> <property name="name"/> <join table="ParentChild" optional="true"> <many-to-one name="parent" column="parent_id" not-null="true"/>
EventManager.java package com.accenture.client; import java.util.HashSet; import org.hibernate.Session;
import org.hibernate.Transaction; import org.hsqldb.lib.Set; import com.accenture.Utilities.HibernateUtil; import com.accenture.domain.*;
public class EventManager { public static void main(String[] args){ Session session = HibernateUtil.currentSession(); Transaction tx = session.beginTransaction(); Parent parent=new Parent(); parent.setName("Father"); Child child1=new Child(); child1.setName("Child1"); child1.setParent(parent); session.save(child1); Child child2=new Child(); child2.setName("Child2"); child2.setParent(parent); session.save(child2); HashSet children =new HashSet(); children.add(child1); children.add(child2); parent.setChildren(children); session.save(parent); tx.commit();
}
HibernateUtil.closeSession(); HibernateUtil.sessionFactory.close();
}
Enforced in the underlying database by a join table. Check the tables. Exercise 2c One to One Primary Key Association Person.java package com.accenture.domain; public class Person { private Long id; private String name; private Employee employee;
public Employee getEmployee() { return employee; } public void setEmployee(Employee employee) { this.employee = employee; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Employee.java package com.accenture.domain; public class Employee { private Long id; private String department; private Person person; public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } }
Employee.hbm.xml <param name="property">employee <property name="name" column="name" type="java.lang.String" /> <property name="department" column="name" type="java.lang.String" />
EventManager.java package com.accenture.client; import import import import
java.util.HashSet; org.hibernate.Session; org.hibernate.Transaction; org.hsqldb.lib.Set;
import com.accenture.Utilities.HibernateUtil; import com.accenture.domain.Employee; import com.accenture.domain.Person; public class EventManager { public static void main(String[] args) { Session session = HibernateUtil.currentSession(); Transaction tx = session.beginTransaction(); Employee employee=new Employee(); employee.setDepartment("Solutions"); Person per=new Person(); per.setName("Accenture"); per.setEmployee(employee);
session.save(per); tx.commit(); HibernateUtil.closeSession(); HibernateUtil.sessionFactory.close(); }
}
Exercise 3a Inheritance Relationships. Other files remains the same. Tab1.java package com.accenture.domain; public class Tab1 extends TblPerClass { protected String desctwo = null; public String getDesctwo() { return desctwo; } public void setDesctwo(String desctwo) { this.desctwo = desctwo; } }
Tab2.java package com.accenture.domain; public class Tab2 extends TblPerClass { protected String desc = null; public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } }
TblPerClass.java package com.accenture.domain; import java.util.Date; public
class TblPerClass { private Long id; protected Date date; public Long getId() { return id; }
private void setId(Long id) { this.id = id; } public Date getDate() { return date; }
}
public void setDate(Date date) { this.date = date; }
TblPerClass.hbm.xml <property name="date" column="DATE" type="java.sql.Date" /> <subclass name="Tab1" discriminator-value="tab1"> <property name="desctwo" column="DESCTWO" type="java.lang.String" /> <subclass name="Tab2" discriminator-value="tab2"> <property name="desc" column="DESC" type="java.lang.String" />
EventManager.java package com.accenture.client; import org.hibernate.Session; import org.hibernate.Transaction; import com.accenture.Utilities.HibernateUtil; import com.accenture.domain.Tab1;
import com.accenture.domain.Tab2; public class EventManager { public static void main(String[] args) { Session session = HibernateUtil.currentSession(); Transaction tx = session.beginTransaction(); Tab1 t3 = new Tab1(); t3.setDesctwo("Hibernate session.save(t3);
Class");
Tab2 t4 = new Tab2(); t4.setDesc("Spring Class"); session.save(t4); tx.commit(); HibernateUtil.closeSession(); HibernateUtil.sessionFactory.close(); } }
Here check the tables. Only TabPerClass is created. No tables are created for the subclasses. Only tables are generated for the super class. Exercise 3b The following example shows all the sub class super Class is not created. Tab5.java package samples; public class Tab5 extends TblPerConcreteClass { protected String xyz1 = null;
}
/** * @return Returns the address. */ public String getXyz1() { return xyz1; } /** * @param address The address to set. */ public void setXyz1(String xyz1) { this.xyz1 = xyz1; }
Tab6.java
package samples; public class Tab6 extends TblPerConcreteClass { protected String xyz2 = null; /** * @return Returns the address. */ public String getXyz2() { return xyz2; } /** * @param address The address to set. */ public void setXyz2(String xyz2) { this.xyz2 = xyz2; } }
TblPerConcreteClass.java package samples; import java.util.Set; public abstract class TblPerConcreteClass { private Long id; protected String description; public Long getId() { return id; } private void setId(Long id) { this.id = id; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }
EntityManager.java package samples; import org.hibernate.Session; import org.hibernate.Transaction;
import com.accenture.Utilities.HibernateUtil; import com.accenture.domain.Tab1; import com.accenture.domain.Tab2; public class EventManager { public static void main(String[] args) { Session session = HibernateUtil.currentSession(); Transaction tx = session.beginTransaction(); Tab5 t3 = new Tab5(); t3.setDescription("Hibernate Class"); session.save(t3); Tab6 t4 = new Tab6(); t4.setXyz2("XYZ2"); session.save(t4); tx.commit(); HibernateUtil.closeSession(); HibernateUtil.sessionFactory.close(); } } TblPerConcreteClass.hbm.xml <property name="description" column="DESCRIPTION" type="java.lang.String" /> <property name="xyz1" column="XYZ1" type="java.lang.String"/>
<property name="description" column="DESCRIPTION" type="java.lang.String" /> <property name="xyz2" column="XYZ2" type="java.lang.String"/>
Another Table Per Sub Class Tab3.java package samples; public class Tab3 extends TblPerSubClass { protected String firstName = null; protected String lastName = null; 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; } }
Tab4.java package samples; public class Tab4 extends TblPerSubClass { protected String name = null; protected String registrationNumber = null; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getRegistrationNumber() {
}
return registrationNumber;
public void setRegistrationNumber(String registrationNumber) { this.registrationNumber = registrationNumber; } }
TblPerSubClass.java package samples; import java.util.Set; public class TblPerSubClass { private Long id; public Long getId() { return id; } private void setId(Long id) { this.id = id; } }
TblPerSubClass.hbm.xml <joined-subclass name="samples.Tab3" table="TAB3"> <property name="firstName" column="FIRST_NAME" type="java.lang.String" /> <property name="lastName" column="LAST_NAME" type="java.lang.String" /> <joined-subclass name="samples.Tab4" table="TAB4"> <property name="name" column="NAME" type="string" /> <property name="registrationNumber" column="REGISTRATION_NUMBER" type="string" />
EventManager.java package samples; import org.hibernate.Session; import org.hibernate.Transaction; import com.accenture.Utilities.HibernateUtil; import com.accenture.domain.Tab1; import com.accenture.domain.Tab2; public class EventManager { public static void main(String[] args) { Session session = HibernateUtil.currentSession(); Transaction tx = session.beginTransaction(); Tab3 t3 = new Tab3(); t3.setFirstName("Tiger"); t3.setLastName("Woods"); session.save(t3); Tab4 t4 = new Tab4(); t4.setName("Accenture"); t4.setRegistrationNumber("1045"); session.save(t4); tx.commit(); HibernateUtil.closeSession(); HibernateUtil.sessionFactory.close(); } } Exercise for the students .Observe the difference.Check the database.
Hibernate Annotations. Employee.java package com.accenture;
import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "employee") public class Employee implements Serializable { public Employee() { } @Id @Column(name = "id") Integer id; @Column(name = "name") String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; }
public String getName() { return name; } public void setName(String name) { this.name = name; } } Example1.java package com.accenture; import org.hibernate.Session;
import org.hibernate.SessionFactory; import org.hibernate.Transaction; public class Example1 { /** * @param args */ public static void main(String[] args) throws Exception { /** Getting the Session Factory and session */ SessionFactory session = HibernateUtil.getSessionFactory(); Session sess = session.getCurrentSession(); /** Starting the Transaction */ Transaction tx = sess.beginTransaction(); /** Creating Pojo */ Employee pojo = new Employee(); pojo.setId(new Integer(5)); pojo.setName("XYZ"); /** Saving POJO */ sess.save(pojo); /** Commiting the changes */ tx.commit(); System.out.println("Record Inserted"); /** Closing Session */ session.close(); } } HibernateUtils.java package com.accenture; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; public class HibernateUtil { private static final SessionFactory sessionFactory; static { try { // Create the SessionFactory from hibernate.cfg.xml sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); } catch (Throwable ex) { // Make sure you log the exception, as it might be swallowed System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); }
}
}
public static SessionFactory getSessionFactory() { return sessionFactory; }
hibernate.cfg.xml <session-factory > <property name="connection.driver_class">org.hsqldb.jdbcDriver <property name="connection.url">jdbc:hsqldb:hsql://localhost:9001/xdb <property name="connection.username">sa <property name="connection.password"> <property name="current_session_context_class">thread <property name="connection.pool_size">10 <property name="dialect">org.hibernate.dialect.HSQLDialect <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider <property name="show_sql">true <property name="hbm2ddl.auto">create
<mapping class="com.accenture.Employee"/>