Q. How will you configure Hibernate?
·
The
configuration files hibernate.cfg.xml (or hibernate.properties) and mapping
files *.hbm.xml are used by the Configuration class to create (i.e. configure
and bootstrap hibernate) the SessionFactory, which in turn creates the Session
instances. Session instances are the primary interface for the persistence
service.
hibernate.cfg.xml (alternatively can use hibernate.properties): These two files are used to configure the hibernate sevice (connection driver class, connection URL, connection username, connection password, dialect etc). If both files are present in the classpath then hibernate.cfg.xml file overrides the settings found in the hibernate.properties file.
Mapping files (*.hbm.xml): These files are used to map persistent objects to a relational database. It is the best practice to store each object in an individual mapping file (i.e mapping file per class) because storing large number of persistent classes into one mapping file can be difficult to manage and maintain. The naming convention is to use the same name as the persistent (POJO) class name. For example Account.class will have a mapping file named Account.hbm.xml. Alternatively, hibernate annotations can be used as part of your persistent class code instead of the *.hbm.xml files.
Q. What is a SessionFactory? Is it a thread-safe object?
A. SessionFactory is Hibernate's concept of a single datastore and is threadsafe so that many threads can access it concurrently and request for sessions and immutable cache of compiled mappings for a single database. A SessionFactory is usually only built once at startup. SessionFactory should be wrapped in some kind of singleton so that it can be easily accessed in an application code.
SessionFactory sessionFactory = new Configuration( ).configure( ).buildSessionfactory( );
Q. What is a Session? Can you share a session object between different threads?
A. Session is a light weight and a non-threadsafe object (No, you cannot share it between threads) that represents a single unit-of-work with the database. Sessions are opened by a SessionFactory and then are closed when all work is complete. Session is the primary interface for the persistence service. A session obtains a database connection lazily (i.e. only when required). To avoid creating too many sessions ThreadLocal class can be used as shown below to get the current session no matter how many times you make call to the currentSession( ) method.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class HibernateUtil {
public static final ThreadLocal local = new ThreadLocal();
public static Session currentSession() throws
HibernateException {
Session session
= (Session) local.get();
//open a new
session if this thread has no session
if(session == null) {
session
= sessionFactory.openSession();
local.set(session);
}
return session;
}
}
|
It is
also vital that you close your session after your unit of work completes.
Note: Keep your Hibernate Session API handy. Quite often, hibernate is used with Spring framework, using the Template design pattern.
Note: Keep your Hibernate Session API handy. Quite often, hibernate is used with Spring framework, using the Template design pattern.
Q. Explain hibernate object states? Explain hibernate objects life cycle?
A.
Persistent objects and collections are short lived single threaded objects, which store the persistent state. These objects synchronize their state with the database depending on your flush strategy (i.e. auto-flush where as soon as setXXX() method is called or an item is removed from a Set, List etc or define your own synchronization points with session.flush(), transaction.commit() calls). If you remove an item from a persistent collection like a Set, it will be removed from the database either immediately or when flush() or commit() is called depending on your flush strategy. They are Plain Old Java Objects (POJOs) and are currently associated with a session. As soon as the associated session is closed, persistent objects become detached objects and are free to use directly as data transfer objects in any application layers like business layer, presentation layer etc.
Detached objects and collections are instances of persistent objects that were associated with a session but currently not associated with a session. These objects can be freely used as Data Transfer Objects without having any impact on your database. Detached objects can be later on attached to another session by calling methods like session.update(), session.saveOrUpdate() etc. and become persistent objects.
Transient objects and collections are instances of persistent objects that were never associated with a session. These objects can be freely used as Data Transfer Objects without having any impact on your database. Transient objects become persistent objects when associated to a session by calling methods like session.save( ), session.persist( ) etc.
Q. What are the benefits of detached objects?
A.
Pros:
- When long transactions are required due to user think-time, it is the best practice to break the long transaction up into two or more transactions. You can use detached objects from the first transaction to carry data all the way up to the presentation layer. These detached objects get modified outside a transaction and later on re-attached to a new transaction via another session.
Cons:
- In general, working with detached objects is quite cumbersome, and it is better not to clutter up the session with them if possible. It is better to discard them and re-fetch them on subsequent requests. This approach is not only more portable but also more efficient because - the objects hang around in Hibernate's cache anyway.
- Also from pure rich domain driven design perspective, it is recommended to use DTOs (DataTransferObjects) and DOs (DomainObjects) to maintain the separation between Service and UI tiers.
Q. When does an object become detached?
A.
1
2
3
|
Session session1 = sessionFactory.openSession();
Car myCar = session1.get(Car.class,
carId); //”myCar” is a persistent object at
this stage.
session1.close();
//once the session is closed “myCar” becomes a detached object
|
you can now pass the “myCar” object all the way upto the presentation tier. It can be modified without any effect to your database table.
1
|
myCar.setColor(“Red”); //no effect on the database
|
When you are ready to persist this change to the database, it can be reattached to another session as shown below:
1
2
3
4
5
|
Session session2 = sessionFactory.openSession();
Transaction tx = session2.beginTransaction();
session2.update(myCar);
//detached object ”myCar” gets re-attached
tx.commit();
//change is synchronized with the database.
session2.close()
|
Q. How does Hibernate distinguish between transient (i.e. newly instantiated) and detached objects?
A.
- Hibernate uses the "version" property, if there is one.
- If not uses the identifier value. No identifier value means a new object. This does work only for Hibernate managed surrogate keys. Does not work for natural keys and assigned (i.e. not managed by Hibernate) surrogate keys.
- Write your own strategy with Interceptor.isUnsaved( ).
Note: When you reattach detached objects, you need to make sure
that the dependent objects are reattached as well.
Q:1 What is Hibernate?
Ans:
Hibernate is an ORM (Object Relational Mapping) and persistent framework. The
framework helps to map plain java object to relational database table using xml
configuration file.
The
framework helps to perform following things.
• Perform
basic CURD operations.
• Write queries referring to java classes (HQL queries).
• Facilities to specify metadata.
• Dirty checking, lazy association fetching.
• Write queries referring to java classes (HQL queries).
• Facilities to specify metadata.
• Dirty checking, lazy association fetching.
Q: 2 Why hibernate and how does it help in the
programming?
Ans: The
main advantage of Hibernate (ORM) framework is that it helps developer to
write a messy SQL. Apart from that ORM provides following benefits.
• Improve
Productivity of the developer by providing high level object oriented API (e.g.
API for easily maintaining the connection to data base, mapping java classes to
relational database tables), less java code to write, helps to avoid writing
SQL query.
• Improved performance by providing sophisticated caching, lazy loading and eager loading features.
• Provide portability, the framework helps to generate database specific SQL for you.
• Improved performance by providing sophisticated caching, lazy loading and eager loading features.
• Provide portability, the framework helps to generate database specific SQL for you.
Q:4 Which settings will be loaded
if both hibernate.properties and hibernat.cf.xml files are present in the
classpath?
Ans: If
both hibernate.properties and hibernate.cfg.xml files are present in the
classpath then hibernate.cfg.xml file will override the settings found in
hibernate.properties. So please make sure that your project should include
either hibernate.properties or hibernate.cfg.xml file.
Q:5 What are the Core interfaces of Hibernate
framework?
Ans:
There are five core interfaces being used extensively in every Hibernate
application. Using these interfaces you can store or retrieve any persistent
objects and also control transactions.
- Session
interface
- SessionFactory interface
- Configuration interface
- Transaction interface
- Query and Criteria interfaces
- SessionFactory interface
- Configuration interface
- Transaction interface
- Query and Criteria interfaces
Q:6 What is the role of Session interface in
Hibernate?
Ans: The
session interface is the primary interface used in Hibernate Application. It is
single threaded sort-lived object and represents conversation between
Application and the persistent store. It helps to create query objects to
retrieve persistent objects.
You can
get the session object from session factory
Session
session = sessionFactory.openSession();
Session
Interface role:
--Wraps a
JDBC connection
--Factory for Transaction
--Holds a mandatory (first-level) cache of persistent objects, used when navigating the object graph or looking up objects by identifier
--Factory for Transaction
--Holds a mandatory (first-level) cache of persistent objects, used when navigating the object graph or looking up objects by identifier
Q: 7 What is the role of SessionFactory?
Ans: The
application obtains session object from SessionFactory interface. Typically there
should be only one sessionFacory for whole application and is loaded during
application initialization. The SessionFactory caches generate SQL Statement
and other mapping metadata that Hibernate use at runtime. It also hold cached
data that has been read in one unit of work and can be reused in a future unit
of work.
You can
get the instance of SessionFactory by the configuration object as below
SessionFactory
sessionFactory = configuration.buildSessionFactory();
Q:8 How do you implement one to one relationship in
Hibernate with XML mapping?
Ans: For
example you have table emp and emp_detail and assuming there is a one to one
relationship between them. For the above tables you have to create
corresponding POJO classes and hbm.xml files.
So for
emp table the java class is Employee.java with property empId and xml file is
emp.hbm.xml.
And for
emp_details the java class is EmployeeDetail.java (properties are name, address
etc.) and xml file is empdetail.hbm.xml.
So the
final code will look like as below
package
com.test.onetoone.mapping
public
class Employee implements java.io.Serializable{
private Integer empId;
private EmployeeDetail empDetail;
}
package com.test.onetoone.mapping
public class EmployeeDetail implements java.io.Serializable{
private Integer empId;
private Employee emp;
private String name;
private String address;
}
----- emp.hbm.xml ----
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.test.onetoone.mapping.Employee" table="emp">
<id name="empId" type="java.lang.Integer">
<column name="EMP_ID" />
<generator class="identity" />
</id>
<one-to-one name="empDetail" class="com.test.onetoone.mapping.EmployeeDetail"
cascade="save-update"></one-to-one>
</class>
</hibernate-mapping>
***********************empdetails.hbm.xml*******************
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.test.onetoone.mapping.EmployeeDetail" table="emp_detail"
catalog="mkyongdb">
<id name="stockId" type="java.lang.Integer">
<column name="EMP_ID" />
<generator class="foreign">
<param name="property">emp</param>
</generator>
</id>
<one-to-one name="emp" class="com.test.onetoone.mapping.Employee"
constrained="true"></one-to-one>
<property name="name" type="string">
<column name="EMP_NAME" length="100" not-null="true" />
</property>
<property name="address" type="string">
<column name="EMP_ADDR" not-null="true" />
</property>
</class>
</hibernate-mapping>
private Integer empId;
private EmployeeDetail empDetail;
}
package com.test.onetoone.mapping
public class EmployeeDetail implements java.io.Serializable{
private Integer empId;
private Employee emp;
private String name;
private String address;
}
----- emp.hbm.xml ----
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.test.onetoone.mapping.Employee" table="emp">
<id name="empId" type="java.lang.Integer">
<column name="EMP_ID" />
<generator class="identity" />
</id>
<one-to-one name="empDetail" class="com.test.onetoone.mapping.EmployeeDetail"
cascade="save-update"></one-to-one>
</class>
</hibernate-mapping>
***********************empdetails.hbm.xml*******************
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.test.onetoone.mapping.EmployeeDetail" table="emp_detail"
catalog="mkyongdb">
<id name="stockId" type="java.lang.Integer">
<column name="EMP_ID" />
<generator class="foreign">
<param name="property">emp</param>
</generator>
</id>
<one-to-one name="emp" class="com.test.onetoone.mapping.Employee"
constrained="true"></one-to-one>
<property name="name" type="string">
<column name="EMP_NAME" length="100" not-null="true" />
</property>
<property name="address" type="string">
<column name="EMP_ADDR" not-null="true" />
</property>
</class>
</hibernate-mapping>
Q:9 How do you implement one to one relationship in
Hibernate with java annotation?
Ans:
Taking the same Employee and Employee Details example of the above question.
Employee.java
package com.test.onetoone.mapping
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name = "emp")
public class Employee implements java.io.Serializable{
private Integer empId;
private EmployeeDetail empDetail;
public Employee(){}
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "EMP_ID", unique = true, nullable = false)
public Integer getEmpId(){
return this.empId;
}
public void setEmpId(Integer empId){
this.empId = empId;
}
@OneToOne(fetch = FetchType.LAZY, mappedBy = "emp", cascade = CascadeType.ALL)
public EmployeeDetail getEmpDetail() {
return this.empDetail;
}
public void setEmpDetail(EmployeeDetail empDetail) {
this.empDetail = empDetail; }
}
package com.test.onetoone.mapping
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name = "emp")
public class Employee implements java.io.Serializable{
private Integer empId;
private EmployeeDetail empDetail;
public Employee(){}
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "EMP_ID", unique = true, nullable = false)
public Integer getEmpId(){
return this.empId;
}
public void setEmpId(Integer empId){
this.empId = empId;
}
@OneToOne(fetch = FetchType.LAZY, mappedBy = "emp", cascade = CascadeType.ALL)
public EmployeeDetail getEmpDetail() {
return this.empDetail;
}
public void setEmpDetail(EmployeeDetail empDetail) {
this.empDetail = empDetail; }
}
File:
EmployeeDetail.java
package
com.test.onetoone.mapping
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
@Entity
@Table(name = "emp_detail")
public class EmployeeDetail implements java.io.Serializable {
private Integer empId;
private Employee emp;
private String name;
private String address;
public EmployeeDetail() {
}
public EmployeeDetail(Employee emp, String name, String address) {
this.emp = emp;
this.name = name;
this.address = address;
}
@GenericGenerator(name = "generator", strategy = "foreign",
parameters = @Parameter(name = "property", value = "emp"))
@Id
@GeneratedValue(generator = "generator")
@Column(name = "EMP_ID", unique = true, nullable = false)
public Integer getEmpId() {
return this.empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
@OneToOne(fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
public Employee getEmp() {
return this.emp; }
public void setEmp(Employee emp) {
this.emp = emp;
}
@Column(name = "ADDRESS", nullable = false, length = 400)
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
@Column(name = "EMP_NAME", nullable = false)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
@Entity
@Table(name = "emp_detail")
public class EmployeeDetail implements java.io.Serializable {
private Integer empId;
private Employee emp;
private String name;
private String address;
public EmployeeDetail() {
}
public EmployeeDetail(Employee emp, String name, String address) {
this.emp = emp;
this.name = name;
this.address = address;
}
@GenericGenerator(name = "generator", strategy = "foreign",
parameters = @Parameter(name = "property", value = "emp"))
@Id
@GeneratedValue(generator = "generator")
@Column(name = "EMP_ID", unique = true, nullable = false)
public Integer getEmpId() {
return this.empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
@OneToOne(fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
public Employee getEmp() {
return this.emp; }
public void setEmp(Employee emp) {
this.emp = emp;
}
@Column(name = "ADDRESS", nullable = false, length = 400)
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
@Column(name = "EMP_NAME", nullable = false)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
3.
Hibernate Configuration File
Puts
annotated classes Employee.java and EmployeeDetail.java in your Hibernate
configuration file, and also MySQL connection details.
File : hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mytestdb</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<mapping class="com.test.onetoone.mapping.Employee" />
<mapping class="com.test.onetoone.mapping.EmployeeDetail" />
</session-factory>
</hibernate-configuration>
File : hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mytestdb</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<mapping class="com.test.onetoone.mapping.Employee" />
<mapping class="com.test.onetoone.mapping.EmployeeDetail" />
</session-factory>
</hibernate-configuration>
Q:10 How do you implement one to many relationships
in Hibernate?
Ans: For
one to many relationships we can consider the example Author and Books (i.e.
one Author can have written many books).
Below code will help you to understand how you can implement one to many relationship in hibernate.
Below code will help you to understand how you can implement one to many relationship in hibernate.
File:
Author.java
package
com.test.one.to.many;
java.util.Set;
public class Author implements java.io.Serializable{
private Integer authorId;
private String authorName;
private Set<Book> books;
// getter and setter
}
File: Book.java
package com.test.one.to.many;
public class Book implements java.io.Serializable{
private Author author;
private Integer bookId;
private String bookName;
// getter and setter
}
File: Author.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.test.one.to.many.Author" table="author">
<id name="authorId" type="java.lang.Integer">
<column name="AUTHOR_ID" />
<generator class="identity" />
</id>
<property name="authorName" type="string">
<column name="AUTHOR_NAME" length="100" not-null="true" unique="true" />
</property>
<set name="books" table="book" inverse="true" lazy="true" fetch="select">
<key>
<column name="AUTHOR_ID" not-null="true" />
</key>
<one-to-many class="com.test.one.to.many.Book" />
</set>
</class>
</hibernate-mapping>
File: Book.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.test.one.to.many.Book" table="book">
<id name="bookId" type="java.lang.Integer">
<column name="BOOK_ID" />
<generator class="identity" />
</id>
<many-to-one name="author" class="com.test.one.to.many.Author" fetch="select">
<column name="AUTHOR_ID" not-null="true" />
</many-to-one>
<property name="bookName" type="string">
<column name="BOOK_NAME" />
</property>
</class>
</hibernate-mapping>
File: hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mytestdb</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<mapping resource="com/test/one/to/many/Author.hbm.xml" />
<mapping resource="com/test/one/to/many/Book.hbm.xml" />
</session-factory>
</hibernate-configuration>
java.util.Set;
public class Author implements java.io.Serializable{
private Integer authorId;
private String authorName;
private Set<Book> books;
// getter and setter
}
File: Book.java
package com.test.one.to.many;
public class Book implements java.io.Serializable{
private Author author;
private Integer bookId;
private String bookName;
// getter and setter
}
File: Author.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.test.one.to.many.Author" table="author">
<id name="authorId" type="java.lang.Integer">
<column name="AUTHOR_ID" />
<generator class="identity" />
</id>
<property name="authorName" type="string">
<column name="AUTHOR_NAME" length="100" not-null="true" unique="true" />
</property>
<set name="books" table="book" inverse="true" lazy="true" fetch="select">
<key>
<column name="AUTHOR_ID" not-null="true" />
</key>
<one-to-many class="com.test.one.to.many.Book" />
</set>
</class>
</hibernate-mapping>
File: Book.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.test.one.to.many.Book" table="book">
<id name="bookId" type="java.lang.Integer">
<column name="BOOK_ID" />
<generator class="identity" />
</id>
<many-to-one name="author" class="com.test.one.to.many.Author" fetch="select">
<column name="AUTHOR_ID" not-null="true" />
</many-to-one>
<property name="bookName" type="string">
<column name="BOOK_NAME" />
</property>
</class>
</hibernate-mapping>
File: hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mytestdb</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<mapping resource="com/test/one/to/many/Author.hbm.xml" />
<mapping resource="com/test/one/to/many/Book.hbm.xml" />
</session-factory>
</hibernate-configuration>
Q:11 How to implement one to many relationships
with Annotation?
Ans: You
can implement one to many relationship with the help Annotation also. Below
code will help you to understand the one to many relationship with java
Annotation.
File : Author.java
package com.test.one.to.many;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "Author")
public class Author implements java.io.Serializable {
private Integer authorId;
private String authorName;
private Set<Book> books;
// getter and setter
public Author() {
}
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "AUTHOR_ID", unique = true, nullable = false)
public Integer getAuthorId() {
return this.authorId;
}
public void setAuthorId(Integer authorId) {
this.authorId = authorId;
}
@Column(name = "AUTHOR_NAME", nullable = false, length = 100)
public String getAuthorName() {
return this.authorName;
}
public void setAuthorName(String authorName) {
this.authorName = authorName;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "author")
public Set<Book> getBooks() {
return this.books;
}
public void setBooks(Set<Book> books) {
this.books = books;
}
}
File : Book.java
package com.test.one.to.many;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
@Entity
@Table(name = "book")
public class Book implements java.io.Serializable {
private Author author;
private Integer bookId;
private String bookName;
public Book() {
}
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "BOOK_ID", unique = true, nullable = false)
public Integer getBookId() {
return this.bookId;
}
public void setBookId(Integer bookId) {
this.bookId = bookId;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "AUTHOR_ID", nullable = false)
public Author getAuthor() {
return this.auther;
}
public void setAuther(Author author) {
this.auther = auther;
}
@Column(name = "BOOK_NAME", length = 400, nulaable=false)
public Float getBookName() {
return this.bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
}
3. Hibernate Configuration File
Puts annotated classes Author.java and Book.java in hibernate.cfg.xml like this :
File : hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mytestdb</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<mapping class="com.test.one.to.many.Author" />
<mapping class="com.test.one.to.many.Book" />
</session-factory>
</hibernate-configuration>
File : Author.java
package com.test.one.to.many;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "Author")
public class Author implements java.io.Serializable {
private Integer authorId;
private String authorName;
private Set<Book> books;
// getter and setter
public Author() {
}
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "AUTHOR_ID", unique = true, nullable = false)
public Integer getAuthorId() {
return this.authorId;
}
public void setAuthorId(Integer authorId) {
this.authorId = authorId;
}
@Column(name = "AUTHOR_NAME", nullable = false, length = 100)
public String getAuthorName() {
return this.authorName;
}
public void setAuthorName(String authorName) {
this.authorName = authorName;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "author")
public Set<Book> getBooks() {
return this.books;
}
public void setBooks(Set<Book> books) {
this.books = books;
}
}
File : Book.java
package com.test.one.to.many;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
@Entity
@Table(name = "book")
public class Book implements java.io.Serializable {
private Author author;
private Integer bookId;
private String bookName;
public Book() {
}
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "BOOK_ID", unique = true, nullable = false)
public Integer getBookId() {
return this.bookId;
}
public void setBookId(Integer bookId) {
this.bookId = bookId;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "AUTHOR_ID", nullable = false)
public Author getAuthor() {
return this.auther;
}
public void setAuther(Author author) {
this.auther = auther;
}
@Column(name = "BOOK_NAME", length = 400, nulaable=false)
public Float getBookName() {
return this.bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
}
3. Hibernate Configuration File
Puts annotated classes Author.java and Book.java in hibernate.cfg.xml like this :
File : hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mytestdb</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<mapping class="com.test.one.to.many.Author" />
<mapping class="com.test.one.to.many.Book" />
</session-factory>
</hibernate-configuration>
Q:12 How will you integrate Hibernate with spring
framework?
Ans: To
integrate hibernate with spring framework, the hibernate configuration will go
in spring configuration file.
The configuration file will look like as below
<beans>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties"></bean>
<!—jdbc.properties database related properties -?
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
p:password="${jdbc.password}"></bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="employeeDAO" class="com.test.dao.EmployeeDaoImpl"></bean>
<bean id="employeeManager" class="com.test.service.EmployeeManagerImpl"></bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
</beans>
The configuration file will look like as below
<beans>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties"></bean>
<!—jdbc.properties database related properties -?
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
p:password="${jdbc.password}"></bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="employeeDAO" class="com.test.dao.EmployeeDaoImpl"></bean>
<bean id="employeeManager" class="com.test.service.EmployeeManagerImpl"></bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
</beans>
Q:13 What are the Collection types in Hibernate?
Ans:
• Bag
• Set
• List
• Array
• Map
• Bag
• Set
• List
• Array
• Map
Q:14 What is HibernateTemplate?
Ans: The
spring framework provides HibernateTemplate
(org.springframework.orm.hibernate.HibernateTemplate) which is kind of helper
class and provides following benefits.
- HibernateTemplate
class simplifies interaction with Hibernate session.
- Common functions are simplified to single method calls.
- Sessions are automatically closed.
- Exception are automatically caught and converted to runtime exceptions.
- Common functions are simplified to single method calls.
- Sessions are automatically closed.
- Exception are automatically caught and converted to runtime exceptions.
Q:15 What is the difference between load() and
get() method?
Ans:
load():
- Use load() method only when you are sure that object you want to read already exists.
- If unique Id of an object does not exists in database then load() method will throw an exception.
- load() method return proxy object default and database won't be hit until the proxy is first invoked.
load():
- Use load() method only when you are sure that object you want to read already exists.
- If unique Id of an object does not exists in database then load() method will throw an exception.
- load() method return proxy object default and database won't be hit until the proxy is first invoked.
get():
- Use
get() method when you are not sure obout the object existance in the database.
- If object does not exists in the database, the get() method will return null.
- get() method will hit database immediately.
- If object does not exists in the database, the get() method will return null.
- get() method will hit database immediately.
Q:16 What is lazy fetching in Hibernate?
Ans: In
Hibernate Lazy fetching is associated with child objects loading for its
parents. Through Hibernate mapping file (.hbm.xml) you can specified the
selection of loading child objects. By default Hibernate does not load child
objects. Lazy=rue means not to load the child objects.
Q:17 What is the difference between merge and
update method?
Ans: Use
update() method when you are sure that session does not contain an already
persistent instance with the same identifier, and merge() if you want to merge
your modifications at any time without consideration of the state of the
session.
Q:18 How do you define sequence generated primary
key in hibernate?
Ans:
Using <generator> tag.
Example:-
<id column="CUST_ID" name="id" type="java.lang.Long">
<generator class="sequence">
<param name="table">SEQUENCE_NAME</param>
<generator>
</id>
Using <generator> tag.
Example:-
<id column="CUST_ID" name="id" type="java.lang.Long">
<generator class="sequence">
<param name="table">SEQUENCE_NAME</param>
<generator>
</id>
Q:19 What are the different types of caches in
Hibernate?
Ans:
Hibernate uses two different type of caches for objects: first-level cache and
second-level cache. First level of cache is associated with Session object,
while second-level of cache is associated with the SessionFactory object. By
default, Hibernate uses first-level of cache on a per-transaction basis.
Hibernate mainly use this cache to reduce the number of SQL queries it needs to
generate within a given transaction.
Q:20 What do you mean by Named – SQL query?
Ans:
Named SQL queries are defined in the mapping xml document and called wherever
required.
Example:
<sql-query name = "empdetails">
<return alias="emp" class="com.test.Employee"/>
SELECT emp.EMP_ID AS {emp.empid},
emp.EMP_ADDRESS AS {emp.address},
emp.EMP_NAME AS {emp.name}
FROM Employee EMP WHERE emp.NAME LIKE :name
</sql-query>
Invoke Named Query :
List people = session.getNamedQuery("empdetails")
.setString("Deepak", name)
.setMaxResults(50)
.list();
Example:
<sql-query name = "empdetails">
<return alias="emp" class="com.test.Employee"/>
SELECT emp.EMP_ID AS {emp.empid},
emp.EMP_ADDRESS AS {emp.address},
emp.EMP_NAME AS {emp.name}
FROM Employee EMP WHERE emp.NAME LIKE :name
</sql-query>
Invoke Named Query :
List people = session.getNamedQuery("empdetails")
.setString("Deepak", name)
.setMaxResults(50)
.list();
1. What
is benefit of using ORM tools?
The main
advantage of ORM like hibernate is that it shields developers from messy SQL.
Apart from this, ORM provides following benefits:
- Improved productivity
- High-level object-oriented API
- Less Java code to write
- No SQL to write
- Improved performance
- Sophisticated caching
- Lazy loading / Eager loading
- Improved maintainability
- A lot less code to write
- Improved portability
ORM
framework generates database-specific SQL for you.
25. How
to implement Optimistic locking in Database?
You can
implement optimistic locks in your DB table in this way (This is how optimistic
locking is done in Hibernate):
- Add
integer "version" column to your table.
- Increase
value of this column with each update of corresponding row.
- To
obtain lock, just read "version" value of row.
- Add
"version = obtained_version" condition to where clause of your update
statement.
- Verify
number of affected rows after update. If no rows were affected - someone has
already modified your entry.
Your
update should look like
UPDATE mytable SET
name = 'Andy', version = 3 WHERE id = 1 and version = 2;
26. What
is Second level Cache and QueryCache in Hibernate?
Second
level Cache is maintained at SessionFactory level and It
improves performance by saving few database round
trip. Another
worth noting point is that second level cache is available to whole application
rather than any particular session.
QueryCache actually stores result of sql query for future
calls. Query cache can be used along with second level cache for
improved performance. Hibernate support various open source
caching solution to implement Query cache e.g. EhCache.
25. How
to implement Optimistic locking in Database?
You can
implement optimistic locks in your DB table in this way (This is how optimistic
locking is done in Hibernate):
- Add
integer "version" column to your table.
-
Increase value of this column with each update of corresponding row.
- To
obtain lock, just read "version" value of row.
- Verify
number of affected rows after update. If no rows were affected - someone has
already modified your entry.
Your
update should look like
UPDATE mytable SET
name = 'Andy', version = 3 WHERE id = 1 and version = 2;
26. What
is Second level Cache and QueryCache in Hibernate?
Second
level Cache is maintained at SessionFactory level and It improves performance by
saving few database round trip. Another worth noting point is
that second level cache is available to whole application rather than any
particular session.
QueryCache actually stores result of sql query for future
calls. Query cache can be used along with second level cache for
improved performance. Hibernate support various open source
caching solution to implement Query cache e.g. EhCache.
No comments:
Post a Comment