Hibernate which is an implementation of JPA(Java Persistence API), is an ORM(Object Relational Mapping) tool which maps database tables with Java Objects and then provides various API’s to perform different types of operations on the data tables.
JPA is a specification for accessing , persisting and managing the data between java objects and the relational database. As the definition says, its API , it is only the specification. There is no implementation for the APIs.JPA is just the guidelines to implement the ORM and there is no underlying code for implementation.Whereas, Hibernate is the actual implementation of JPA guidelines.
EntityManager is an interface used to implement the persistence property to access entities in an application's persistent context.It provides the following 2 tpes of interfaces.
1.2. Application-managed Entitymanager
1. Using the container injection
2. Using the EntityManagerFactory interface
3. Looking up the EntityManager through JNDI.
To create a session factory in hibernate, an object of configuration is created first which refers to the path of configuration file and then for that configuration, session factory is created as given in the example below:
Configuration config = new Configuration();
config.addResource("configuration.hbm.xml");
config.setProperties( System.getProperties() );
SessionFactory sessions = config.buildSessionFactory();
Insertable and updatable parameter control the behaviour of the persistent provider. If the insertable parameter is set to false, then the specified field or property is not included in the insert statement.
If the updatable parameter is set to false, then the field or property of an entity can't be updated in the DB.
@Column(name = "CUST_ID", insertable = "false", updatable = "false")
@Enumerated indicates that the field's persistent property should be stored in the form of an Enumeration. The possible values of EnumType can be ORDINAL or STRING.
@Enumerated(EnumType.ORDINAL) - Ordinal returns its posiion in its enum declaration, lke 0, 1, 2
@Enumerated(EnumType.STRING) - String value of the enum is saved in the DB.
The DATE, TIME, TIMESTAMP types can be used to map a temporal type.
@Temporal(TemporalType.DATE)
potected Date createdDate;
If no value is specified for the TemporalType parameter of the @Temporal annotations, the TIMESAMP i selected as default value.
HQL is the query language used in Hibernate which is an extension of SQL. HQL is very efficient, simple and flexible query language to do various type of operations on relational database without writing complex database queries. We write HQL based on our entity model classes and their relationship.
Following are some key benefits of using Hibernate template:
1. Session closing is automated.
2. Interaction with hibernate session is simplified.
3. Exception handling is automated.
We need to add following in hibernate configuration file to enable viewing SQL on the console for debugging purposes:
<property name=”show_sql”>true</property>
1.Hibernate can be used seamlessly with any type of database as its database independent while in case of JDBC, developer has to write database specific queries.
2.Using hibernate, developer doesn’t need to be an expert of writing complex queries as HQL simplifies query writing process while in case of JDBC, its job of developer to write and tune queries.
3.In case of hibernate, there is no need to create connection pools as hibernate does all connection handling automatically while in case of JDBC, connection pools need to be created.
These interfaces are used in the application to receive a notification when some object events occur. Like when an object is loaded, saved or deleted. There is no need to implement callbacks in hibernate applications, but they're useful for implementing certain kinds of generic functionality.
Objects which have been detached and are no longer associated with any persistent entities can be reattached by calling session.merge() method of session class.
Hibernate second level cache can be disabled using any of the following ways:
1.By setting use_second_level_cache as false.
2.By using CACHEMODE.IGNORE
3.Using cache provider as org.hibernate.cache.NoCacheProvider
There are five collection types in hibernate used for one-to-many relationship mappings.
Bag
Set
List
Array
Map
The main difference between sorted and ordered collection is that sorted collection sort the data in JVM's heap memory using Java's collection framework sorting methods while ordered collection is sorted using order by clause in the database itself. A sorted collection is more suited for small dataset but for a large dataset, it's better to use ordered collection to avoid OutOfMemoryError in Java application.
There are four entity states defined in hibernate:
New (transient): an entity is new if it has just been instantiated using the new operator, and it is not associated with a persistence context. It has no persistent representation in the database and no identifier value has been assigned.
Managed (persistent): a managed entity instance is an instance with a persistent identity that is currently associated with a persistence context.
Detached: the entity instance is an instance with a persistent identity that is no longer associated with a persistence context, usually because the persistence context was closed or the instance was evicted from the context.
Removed: a removed entity instance is an instance with a persistent identity, associated with a persistence context, but scheduled for removal from the database.
A Session object uses the first-level cache.Second level cache is used at SessionFactory level.
The N+1 SELECT problem is a result of lazy loading and load on demand fetching strategy. In this case, Hibernate ends up executing N+1 SQL queries to populate a collection of N elements. For example, if you have a List of N Items where each Item has a dependency on a collection of Bid object. Now if you want to find the highest bid for each item then Hibernate will fire 1 query to load all items and N subsequent queries to load Bid for each item. So in order to find the highest bid for each item your application end up firing N+1 queries.
This is the follow-up question of previous Hibernate interview question. If you answer the last query correctly then you would be most likely asked this one. Here are some strategies to solve the N+1 problem:
1. pre-fetching in batches, this will reduce N+1 problem to N/K + 1 problem where K is size of batch.
2. subselect fetching strategy.
3. disabling lazy loading
This is another common Hibernate interview question. Hibernate provides the out-of-box caching solution but there are many caches e.g. first level cache, second level cache and query cache.
1.>First level cache is maintained at Session level and cannot be disabled but the second level cache is required to be configured with external cache provider like EhCache.
2.second level cache is maintained at SessionFactory level and shared by all sessions
No, Session object is not thread-safe in Hibernate and intended to be used with-in single thread in the application.
Hibernate SessionFactory getCurrentSession() method returns the session bound to the context. But for this to work, we need to configure it in hibernate configuration file. Since this session object belongs to the hibernate context, we don’t need to close it. Once the session factory is closed, this session object gets closed.
<property name="hibernate.current_session_context_class">thread</property>
Hibernate SessionFactory openSession() method always opens a new session. We should close this session object once we are done with all the database operations. We should open a new session for each request in multi-threaded environment.
SessionFactory is both Immutable and thread-safe and it has just one single instance in Hibernate application. It is used to create Session object and it also provide caching by storing SQL queries stored by multiple session. The second level cache is maintained at SessionFactory level. This can be a difficult and tricky question for less experienced Java developers who are not familiar with thread-safety and Immutability.
Defines the field which owns the relationship. This element is specified on the inverse(non-owning) side of the association. It is only needed when relationship is unidirectional.
Owning side is the entity having foreign key column.
Lazy initialization means you don't initialize entire object, it only initializes the first level variables(member variable), t initializes the list when we access it. e.g. Supose an user have 100 list of addresses that he has visited and when we get details it only fetchesnthe first level variable but not the list.
Both are from session interfce and both will be used for retrieving object from DB.
Session.load(123) - it will return a proxy object with an unique identifier 123. It will hit the DB only when we try to retrieve the other properties of the object and if the object is not found in the DB it wil throw ObjectNotFoundException.
But when we call session .get(), it will directly hit the DB immmediately and returns the original object. If the object is not found in the DB, it returns null.
Criteria is a simplified API for retrieving entities by composing Criterion objects also known as Criterion query. This is a very convenient approach for functionality like "search" screens where you can filter data on multiple conditions as shown in the following example:
List books = session.createCriteria(Employee.class)
.add(Restrictions.eq("name", "Dhiraj") )
.add(Restrictions.like("profile", "Lead"))
.addOrder(Order.asc("name") )
.list();
For web applications, it’s always best to allow servlet container to manage the connection pool. That’s why we define JNDI resource for DataSource and we can use it in the web application. It’s very easy to use in Hibernate, all we need is to remove all the database specific properties and use below property to provide the JNDI DataSource name.
Following are collection types used in Hibernate.
Array
Map
Bag
Set
List
Dirty checking feature of the Hibernate allows users or developers to avoid time consuming data base write actions. This feature makes necessary updations and changes to the fields which require a change, remaining fields are left unchanged or untouched.
Persist takes n entity instance, adds it to context and makes that instance managed i.e. future updates to the entity will be traced.
Merge creates a new instance of your entity, copies the state from supplied entity and make the new copy managed.
Table Per Hierarchy - single table is required to map the whole hierarchy, an extra column (known as discriminator column) is added to identify the class. Table Per Concrete class - tables are created as per class. But duplicate column is added in subclass tables. Table Per Subclass - tables are created as per class but related by foreign key. So there are no duplicate columns.