Java Hibernate 面试问题与回答

Hibernate是Java应用中最广泛使用的ORM工具之一。它在企业应用程序中广泛用于数据库操作。因此,我决定撰写一篇关于Hibernate面试问题的文章,以在面试前温习您的知识。无论您是新手还是有经验的人,掌握Hibernate ORM工具的知识都有助于成功通过面试。在这里,我提供了一些重要的Hibernate面试问题及答案,帮助您温习知识并给面试官留下深刻印象。就像其他面试问题文章一样,我可能会在将来添加更多问题到这个列表中,因此您可能希望将其收藏以备将来参考。 最近我写了很多关于Hibernate的文章,其中大多数包含完整可下载的项目。我将根据需要提供对它们的引用,您可以通过它们来复习知识。

Hibernate面试问题

  1. 什么是Hibernate框架?
  2. 什么是Java持久化API(JPA)?
  3. 使用Hibernate框架的重要好处有哪些?
  4. Hibernate相对于JDBC的优势是什么?
  5. 列举一些Hibernate框架中重要的接口有哪些?
  6. Hibernate配置文件是什么?
  7. Hibernate映射文件是什么?
  8. 列举一些用于Hibernate映射的重要注解?
  9. Hibernate SessionFactory是什么,如何配置?
  10. Hibernate SessionFactory是线程安全的吗?
  11. Hibernate Session是什么,如何获取?
  12. Hibernate Session是线程安全的吗?
  13. openSession和getCurrentSession之间有什么区别?
  14. Hibernate Session的get()和load()方法之间有什么区别?
  15. Hibernate缓存是什么?解释一下Hibernate一级缓存?
  16. 如何使用EHCache配置Hibernate二级缓存?
  17. 实体Bean的不同状态有哪些?
  18. Hibernate Session的merge()调用有什么用途?
  19. Hibernate save()、saveOrUpdate()和persist()方法之间有什么区别?
  20. 如果在实体 bean 中没有 no-args 构造函数会发生什么?
  21. 有序集合和排序集合有什么区别,哪一个更好?
  22. Hibernate 中有哪些集合类型?
  23. 如何在 Hibernate 中实现联接(Joins)?
  24. 为什么不应将实体类(Entity Class)定义为 final?
  25. HQL 是什么,它有什么好处?
  26. Hibernate 中的查询缓存是什么?
  27. 在 Hibernate 中是否可以执行本地 SQL 查询?
  28. Hibernate 中支持本地 SQL 查询的好处是什么?
  29. 什么是命名 SQL 查询?
  30. 命名 SQL 查询的好处是什么?
  31. Hibernate Criteria API 的好处是什么?
  32. 如何在日志文件中记录 Hibernate 生成的 SQL 查询?
  33. Hibernate 代理是什么,它如何在懒加载中起作用?
  34. 如何在 Hibernate 中实现关联关系?
  35. Hibernate 中事务管理是如何工作的?
  36. 级联是什么,有哪些不同类型的级联?
  37. 如何在Hibernate应用程序中集成log4j日志记录?
  38. 如何在应用程序服务器JNDI数据源中使用Hibernate框架?
  39. 如何集成Hibernate和Spring框架?
  40. HibernateTemplate类是什么?
  41. 如何将Hibernate与Servlet或Struts2 Web应用程序集成?
  42. Hibernate框架中使用了哪些设计模式?
  43. 使用Hibernate框架的最佳实践有哪些?
  44. 什么是Hibernate Validator框架?
  45. Hibernate Tools Eclipse插件的好处是什么?

Hibernate面试问题与答案

  1. Hibernate框架是什么?

    对象关系映射或ORM是一种编程技术,用于将应用程序领域模型对象映射到关系数据库表。Hibernate是基于Java的ORM工具,提供了将应用程序领域对象映射到关系数据库表以及反之的框架。Hibernate提供了Java持久化API的参考实现,使其成为一种具有松散耦合优势的ORM工具的不错选择。我们可以使用Hibernate持久化API进行CRUD操作。Hibernate框架提供了将普通的Java对象映射到传统数据库表的选项,可使用JPA注解以及基于XML的配置。同样,Hibernate配置灵活,可以通过XML配置文件以及以编程方式进行。如果您想快速了解Hibernate框架的用法,可以查看Hibernate入门教程

  2. 什么是Java持久化API(JPA)?

    Java持久化API(JPA)提供了管理应用程序中关系数据的规范。当前的JPA版本为2.1,于2011年7月启动,作为JSR 338。JPA 2.1于2013年5月22日正式批准。JPA规范在javax.persistence包中使用注解进行定义。使用JPA注解有助于我们编写与实现无关的代码。

  3. 使用Hibernate框架的重要好处是什么?

    使用Hibernate框架的一些重要好处包括:

    1. Hibernate消除了JDBC中的所有样板代码,并负责管理资源,因此我们可以专注于业务逻辑。
    2. Hibernate框架支持XML和JPA注解,使我们的代码实现独立性更强。
    3. Hibernate提供了一个强大的查询语言(HQL),类似于SQL。但是,HQL是完全面向对象的,理解继承、多态和关联等概念。
    4. Hibernate是来自Red Hat社区的开源项目,被全球广泛使用。这使其比其他选择更好,因为学习曲线较小,有大量在线文档和在论坛中易于获取帮助。
    5. Hibernate易于与其他Java EE框架集成,它非常流行,以至于Spring框架提供了与Spring应用程序集成Hibernate的内置支持。
    6. Hibernate支持使用代理对象进行延迟初始化,并且仅在需要时执行实际的数据库查询。
    7. Hibernate缓存帮助我们获得更好的性能。
    8. 对于特定于数据库供应商的功能,Hibernate很适合,因为我们还可以执行本地SQL查询。总体而言,Hibernate是当前市场上ORM工具的最佳选择,它包含您在ORM工具中所需的所有功能。
  4. Hibernate相对于JDBC的优势是什么?

    Hibernate框架相对于JDBC的一些重要优势包括:

    1. Hibernate消除了JDBC API带来的大量样板代码,使代码看起来更清晰和可读。
    2. Hibernate支持继承、关联和集合。这些特性在JDBC API中是不存在的。
    3. Hibernate隐式地提供事务管理,实际上大多数查询都不能在事务外执行。在JDBC API中,我们需要编写代码来进行事务管理,使用commit和rollback。在JDBC事务管理中了解更多信息。
    4. JDBC API抛出的是一个受检异常SQLException,因此我们需要编写很多try-catch块代码。大多数情况下,在每个JDBC调用中都是多余的,并且用于事务管理。Hibernate封装了JDBC异常并抛出未受检异常JDBCExceptionHibernateException,因此我们不需要编写处理它的代码。Hibernate内置的事务管理消除了try-catch块的使用。
    5. Hibernate查询语言(HQL)更加面向对象且接近Java编程语言。对于JDBC,我们需要编写本地的SQL查询。
    6. Hibernate支持缓存,对性能更有利,而JDBC查询不会被缓存,因此性能较低。
    7. Hibernate提供了一个选项,通过它我们可以创建数据库表,而对于JDBC,表必须在数据库中存在。
    8. Hibernate配置帮助我们使用类似于JDBC的连接以及JNDI数据源进行连接池。这在企业应用程序中是非常重要的特性,在JDBC API中完全缺失。
    9. Hibernate支持JPA注解,因此代码与实现无关,可以轻松替换为其他ORM工具。而JDBC代码与应用程序紧密耦合。
  5. 列举一些Hibernate框架的重要接口?

Some of the important interfaces of Hibernate framework are:
1.  **SessionFactory (org.hibernate.SessionFactory)**: SessionFactory is an immutable thread-safe cache of compiled mappings for a single database. We need to initialize SessionFactory once and then we can cache and reuse it. SessionFactory instance is used to get the Session objects for database operations.
2.  **Session (org.hibernate.Session)**: Session is a single-threaded, short-lived object representing a conversation between the application and the persistent store. It wraps JDBC `java.sql.Connection` and works as a factory for `org.hibernate.Transaction`. We should open session only when it's required and close it as soon as we are done using it. Session object is the interface between java application code and hibernate framework and provide methods for CRUD operations.
3.  **Transaction (org.hibernate.Transaction)**: Transaction is a single-threaded, short-lived object used by the application to specify atomic units of work. It abstracts the application from the underlying JDBC or JTA transaction. A org.hibernate.Session might span multiple org.hibernate.Transaction in some cases.
  1. 什么是Hibernate配置文件?

Hibernate configuration file contains database specific configurations and used to initialize SessionFactory. We provide database credentials or JNDI resource information in the hibernate configuration xml file. Some other important parts of hibernate configuration file is Dialect information, so that hibernate knows the database type and mapping file or class details.
  1. 什么是Hibernate映射文件?

Hibernate mapping file is used to define the entity bean fields and database table column mappings. We know that JPA annotations can be used for mapping but sometimes XML mapping file comes handy when we are using third party classes and we can't use annotations.
  1. 列举一些用于Hibernate映射的重要注解?

Hibernate supports JPA annotations and it has some other annotations in `org.hibernate.annotations` package. Some of the important JPA and hibernate annotations used are:

1.  **javax.persistence.Entity**: Used with model classes to specify that they are entity beans.
2.  **javax.persistence.Table**: Used with entity beans to define the corresponding table name in database.
3.  **javax.persistence.Access**: Used to define the access type, either field or property. Default value is field and if you want hibernate to use getter/setter methods then you need to set it to property.
4.  **javax.persistence.Id**: Used to define the primary key in the entity bean.
5.  **javax.persistence.EmbeddedId**: Used to define composite primary key in the entity bean.
6.  **javax.persistence.Column**: Used to define the column name in database table.
7.  **javax.persistence.GeneratedValue**: Used to define the strategy to be used for generation of primary key. Used in conjunction with `javax.persistence.GenerationType` enum.
8.  **javax.persistence.OneToOne**: Used to define the one-to-one mapping between two entity beans. We have other similar annotations as `OneToMany`, `ManyToOne` and `ManyToMany`
9.  **org.hibernate.annotations.Cascade**: Used to define the cascading between two entity beans, used with mappings. It works in conjunction with `org.hibernate.annotations.CascadeType`
10.  **javax.persistence.PrimaryKeyJoinColumn**: Used to define the property for foreign key. Used with `org.hibernate.annotations.GenericGenerator` and `org.hibernate.annotations.Parameter`

Here are two classes showing usage of these annotations.

```
package com.journaldev.hibernate.model;

import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;

@Entity
@Table(name = "EMPLOYEE")
@Access(value=AccessType.FIELD)
public class Employee {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "emp_id")
	private long id;

	@Column(name = "emp_name")
	private String name;

	@OneToOne(mappedBy = "employee")
	@Cascade(value = org.hibernate.annotations.CascadeType.ALL)
	private Address address;

	//getter和setter方法
}
```

```
package com.journaldev.hibernate.model;

import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;

@Entity
@Table(name = "ADDRESS")
@Access(value=AccessType.FIELD)
public class Address {

	@Id
	@Column(name = "emp_id", unique = true, nullable = false)
	@GeneratedValue(generator = "gen")
	@GenericGenerator(name = "gen", strategy = "foreign", parameters = { @Parameter(name = "property", value = "employee") })
	private long id;

	@Column(name = "address_line1")
	private String addressLine1;

	@OneToOne
	@PrimaryKeyJoinColumn
	private Employee employee;

	//getter和setter方法
}
```
  1. Hibernate SessionFactory是什么,如何配置?

SessionFactory is the factory class used to get the Session objects. SessionFactory is responsible to read the hibernate configuration parameters and connect to the database and provide Session objects. Usually an application has a single SessionFactory instance and threads servicing client requests obtain Session instances from this factory. The internal state of a SessionFactory is immutable. Once it is created this internal state is set. This internal state includes all of the metadata about Object/Relational Mapping. SessionFactory also provide methods to get the Class metadata and Statistics instance to get the stats of query executions, second level cache details etc.
  1. Hibernate SessionFactory是线程安全的吗?

Internal state of SessionFactory is immutable, so it's thread safe. Multiple threads can access it simultaneously to get Session instances.
  1. Hibernate Session是什么,如何获取?

Hibernate Session is the interface between java application layer and hibernate. This is the core interface used to perform database operations. Lifecycle of a session is bound by the beginning and end of a transaction. Session provide methods to perform create, read, update and delete operations for a persistent object. We can execute HQL queries, SQL native queries and create criteria using Session object.
  1. Hibernate Session是线程安全的吗?

Hibernate Session object is not thread safe, every thread should get it's own session instance and close it after it's work is finished.
  1. openSession 和 getCurrentSession 之间有什么区别?

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. There is another method openStatelessSession() that returns stateless session, for more details with examples please read [Hibernate openSession vs getCurrentSession](/community/tutorials/hibernate-sessionfactory).
  1. Hibernate Session 的 get() 和 load() 方法有什么区别?

Hibernate session comes with different methods to load data from database. get and load are most used methods, at first look they seems similar but there are some differences between them.

1.  get() loads the data as soon as it's called whereas load() returns a proxy object and loads data only when it's actually required, so load() is better because it support lazy loading.
2.  Since load() throws exception when data is not found, we should use it only when we know data exists.
3.  We should use get() when we want to make sure data exists in the database.

For clarification regarding the differences, please read [Hibernate get vs load](/community/tutorials/hibernate-session-get-vs-load-difference-with-examples).
  1. 什么是Hibernate缓存?解释一下Hibernate一级缓存?

As the name suggests, hibernate caches query data to make our application faster. Hibernate Cache can be very useful in gaining fast application performance if used correctly. The idea behind cache is to reduce the number of database queries, hence reducing the throughput time of the application. Hibernate first level cache is associated with the Session object. Hibernate first level cache is enabled by default and there is no way to disable it. However hibernate provides methods through which we can delete selected objects from the cache or clear the cache completely. Any object cached in a session will not be visible to other sessions and when the session is closed, all the cached objects will also be lost. For better explanation, please read [Hibernate First Level Cache](/community/tutorials/hibernate-caching-first-level-cache).
  1. 如何使用EHCache配置Hibernate二级缓存?

EHCache is the best choice for utilizing hibernate second level cache. Following steps are required to enable EHCache in hibernate application.
-   Add hibernate-ehcache dependency in your maven project, if it's not maven then add corresponding jars.
    
    ```
    <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-ehcache</artifactId>
            <version>4.3.5.Final</version>
    </dependency>
    ```
    
-   Add below properties in hibernate configuration file.
    
    ```
    <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
             
    <!-- For singleton factory -->
    <!-- <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</property>
    -->
              
    <!-- enable second level cache and query cache -->
    <property name="hibernate.cache.use_second_level_cache">true</property>
    <property name="hibernate.cache.use_query_cache">true</property>
    <property name="net.sf.ehcache.configurationResourceName">/myehcache.xml</property>
    ```
    
-   Create EHCache configuration file, a sample file myehcache.xml would look like below.
    
    ```
    <?xml version="1.0" encoding="UTF-8"?>
    <ehcache xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
        monitoring="autodetect" dynamicConfig="true">
     
        <diskStore path="java.io.tmpdir/ehcache" />
     
        <defaultCache maxEntriesLocalHeap="10000" eternal="false"
            timeToIdleSeconds="120" timeToLiveSeconds="120" diskSpoolBufferSizeMB="30"
            maxEntriesLocalDisk="10000000" diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU" statistics="true">
            <persistence strategy="localTempSwap" />
        </defaultCache>
     
        <cache name="employee" maxEntriesLocalHeap="10000" eternal="false"
            timeToIdleSeconds="5" timeToLiveSeconds="10">
            <persistence strategy="localTempSwap" />
        </cache>
     
        <cache name="org.hibernate.cache.internal.StandardQueryCache"
            maxEntriesLocalHeap="5" eternal="false" timeToLiveSeconds="120">
            <persistence strategy="localTempSwap" />
        </cache>
     
        <cache name="org.hibernate.cache.spi.UpdateTimestampsCache"
            maxEntriesLocalHeap="5000" eternal="true">
            <persistence strategy="localTempSwap" />
        </cache>
    </ehcache>
    ```
    
-   Annotate entity beans with @Cache annotation and caching strategy to use. For example,
    
    ```
    import org.hibernate.annotations.Cache;
    import org.hibernate.annotations.CacheConcurrencyStrategy;
    
    @Entity
    @Table(name = "ADDRESS")
    @Cache(usage=CacheConcurrencyStrategy.READ_ONLY, region="employee")
    public class Address {
    
    }
    ```
    
That's it, we are done. Hibernate will use the EHCache for second level caching, read [Hibernate EHCache Example](/community/tutorials/hibernate-ehcache-hibernate-second-level-cache) for a complete example with explanation.
  1. 实体 bean 的不同状态是什么?

An entity bean instance can exist is one of the three states.
1.  **Transient**: When an object is never persisted or associated with any session, it's in transient state. Transient instances may be made persistent by calling save(), persist() or saveOrUpdate(). Persistent instances may be made transient by calling delete().
2.  **Persistent**: When an object is associated with a unique session, it's in persistent state. Any instance returned by a get() or load() method is persistent.
3.  **Detached**: When an object is previously persistent but not associated with any session, it's in detached state. Detached instances may be made persistent by calling update(), saveOrUpdate(), lock() or replicate(). The state of a transient or detached instance may also be made persistent as a new persistent instance by calling merge().
  1. Hibernate Session 的 merge() 调用有什么作用?

Hibernate merge can be used to update existing values, however this method create a copy from the passed entity object and return it. The returned object is part of persistent context and tracked for any changes, passed object is not tracked. For example program, read [Hibernate merge](/community/tutorials/hibernate-session-merge-vs-update-save-saveorupdate-persist-example).
  1. Hibernate的save()、saveOrUpdate()和persist()方法有什么区别?

Hibernate save can be used to save entity to database. Problem with save() is that it can be invoked without a transaction and if we have mapping entities, then only the primary object gets saved causing data inconsistencies. Also save returns the generated id immediately. Hibernate persist is similar to save with transaction. I feel it's better than save because we can't use it outside the boundary of transaction, so all the object mappings are preserved. Also persist doesn't return the generated id immediately, so data persistence happens when needed. Hibernate saveOrUpdate results into insert or update queries based on the provided data. If the data is present in the database, update query is executed. We can use saveOrUpdate() without transaction also, but again you will face the issues with mapped objects not getting saved if session is not flushed. For example usage of these methods, read [Hibernate save vs persist](/community/tutorials/hibernate-session-merge-vs-update-save-saveorupdate-persist-example).
  1. 如果实体Bean中没有无参构造函数会发生什么?

Hibernate uses [Reflection API](/community/tutorials/java-reflection-example-tutorial) to create instance of Entity beans, usually when you call get() or load() methods. The method `Class.newInstance()` is used for this and it requires no-args constructor. So if you won't have no-args constructor in entity beans, hibernate will fail to instantiate it and you will get `HibernateException`.
  1. 排序集合和有序集合有什么区别,哪一个更好?

When we use Collection API sorting algorithms to sort a collection, it's called sorted list. For small collections, it's not much of an overhead but for larger collections it can lead to slow performance and OutOfMemory errors. Also the entity beans should implement `Comparable` or `Comparator` interface for it to work, read more at [java object list sorting](/community/tutorials/comparable-and-comparator-in-java-example). If we are using Hibernate framework to load collection data from database, we can use it's Criteria API to use "order by" clause to get ordered list. Below code snippet shows you how to get it.

```
List<Employee> empList = session.createCriteria(Employee.class)
						.addOrder(Order.desc("id")).list();
```

Ordered list is better than sorted list because the actual sorting is done at database level, that is fast and doesn't cause memory issues.
  1. Hibernate 中有哪些集合类型?

There are five collection types in hibernate used for one-to-many relationship mappings.
1.  Bag
2.  Set
3.  List
4.  Array
5.  Map
  1. 如何在Hibernate中实现连接?

There are various ways to implement joins in hibernate.
-   Using associations such as one-to-one, one-to-many etc.
-   Using JOIN in the HQL query. There is another form "join fetch" to load associated data simultaneously, no lazy loading.
-   We can fire native sql query and use join keyword.
  1. 为什么我们不应该将实体类(Entity Class)定义为final?

Hibernate use proxy classes for lazy loading of data, only when it's needed. This is done by extending the entity bean, if the entity bean will be final then lazy loading will not be possible, hence low performance.
  1. 什么是HQL以及它的好处是什么?

Hibernate Framework comes with a powerful object-oriented query language – Hibernate Query Language (HQL). It’s very similar to SQL except that we use Objects instead of table names, that makes it more close to object oriented programming. Hibernate query language is case-insensitive except for java class and variable names. So SeLeCT is the same as sELEct is the same as SELECT, but com.journaldev.model.Employee is not same as com.journaldev.model.EMPLOYEE. The HQL queries are cached but we should avoid it as much as possible, otherwise we will have to take care of associations. However it's a better choice than native sql query because of Object-Oriented approach. Read more at [HQL Example](/community/tutorials/hibernate-query-language-hql-example-tutorial).
  1. 在Hibernate中,什么是查询缓存?

Hibernate implements a cache region for queries resultset that integrates closely with the hibernate second-level cache. This is an optional feature and requires additional steps in code. This is only useful for queries that are run frequently with the same parameters. First of all we need to configure below property in hibernate configuration file.

```
<property name="hibernate.cache.use_query_cache">true</property>
```

And in code, we need to use setCacheable(true) method of Query, quick example looks like below.

```
Query query = session.createQuery("from Employee");
query.setCacheable(true);
query.setCacheRegion("ALL_EMP");
```
  1. 我们可以在Hibernate中执行原生SQL查询吗?

Hibernate provide option to execute native SQL queries through the use of `SQLQuery` object. For normal scenarios, it is however not the recommended approach because we loose benefits related to hibernate association and hibernate first level caching. Read more at [Hibernate Native SQL Query Example](/community/tutorials/hibernate-native-sql-query-example).
  1. 在Hibernate中支持本地SQL查询有什么好处?

Native SQL Query comes handy when we want to execute database specific queries that are not supported by Hibernate API such as query hints or the CONNECT keyword in Oracle Database.
  1. 什么是命名SQL查询?

Hibernate provides Named Query that we can define at a central location and use them anywhere in the code. We can created named queries for both HQL and Native SQL. Hibernate Named Queries can be defined in Hibernate mapping files or through the use of JPA annotations @NamedQuery and @NamedNativeQuery.
  1. 命名 SQL 查询的好处是什么?

Hibernate Named Query helps us in grouping queries at a central location rather than letting them scattered all over the code. Hibernate Named Query syntax is checked when the hibernate session factory is created, thus making the application fail fast in case of any error in the named queries. Hibernate Named Query is global, means once defined it can be used throughout the application. However one of the major disadvantage of Named query is that it’s hard to debug, because we need to find out the location where it’s defined.
  1. Hibernate Criteria API 有什么好处?

Hibernate provides Criteria API that is more object oriented for querying the database and getting results. We can’t use Criteria to run update or delete queries or any DDL statements. It’s only used to fetch the results from the database using more object oriented approach. Some of the common usage of Criteria API are:

-   Criteria API provides Projection that we can use for aggregate functions such as sum(), min(), max() etc.
-   Criteria API can be used with ProjectionList to fetch selected columns only.
-   Criteria API can be used for join queries by joining multiple tables, useful methods are createAlias(), setFetchMode() and setProjection()
-   Criteria API can be used for fetching results with conditions, useful methods are add() where we can add Restrictions.
-   Criteria API provides addOrder() method that we can use for ordering the results.

Learn some quick examples at [Hibernate Criteria Example](/community/tutorials/hibernate-criteria-example-tutorial).
  1. 如何将Hibernate生成的SQL查询记录在日志文件中?

We can set below property for hibernate configuration to log SQL queries.

```
        <property name="hibernate.show_sql">true</property>
```

However we should use it only in Development or Testing environment and turn it off in production environment.
  1. Hibernate代理是什么,它如何帮助延迟加载?

Hibernate uses proxy object to support lazy loading. Basically when you load data from tables, hibernate doesn't load all the mapped objects. As soon as you reference a child or lookup object via getter methods, if the linked entity is not in the session cache, then the proxy code will go to the database and load the linked object. It uses javassist to effectively and dynamically generate sub-classed implementations of your entity objects.
  1. 如何在Hibernate中实现关联关系?

We can easily implement one-to-one, one-to-many and many-to-many relationships in hibernate. It can be done using JPA annotations as well as XML based configurations. For better understanding, you should go through following tutorials.
1.  [Hibernate One to One Mapping](/community/tutorials/hibernate-one-to-one-mapping-example-annotation)
2.  [Hibernate One to Many Mapping](/community/tutorials/hibernate-one-to-many-mapping-annotation)
3.  [Hibernate Many to Many Mapping](/community/tutorials/hibernate-many-to-many-mapping-join-tables)
  1. Hibernate中事务管理的工作原理是什么?

Transaction management is very easy in hibernate because most of the operations are not permitted outside of a transaction. So after getting the session from SessionFactory, we can call session `beginTransaction()` to start the transaction. This method returns the Transaction reference that we can use later on to either commit or rollback the transaction. Overall hibernate transaction management is better than JDBC transaction management because we don't need to rely on exceptions for rollback. Any exception thrown by session methods automatically rollback the transaction.
  1. 什么是级联,有哪些不同类型的级联?

When we have relationship between entities, then we need to define how the different operations will affect the other entity. This is done by cascading and there are different types of it. Here is a simple example of applying cascading between primary and secondary entities.

```
import org.hibernate.annotations.Cascade;

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

@OneToOne(mappedBy = "employee")
@Cascade(value = org.hibernate.annotations.CascadeType.ALL)
private Address address;

}
```

Note that Hibernate CascadeType enum constants are little bit different from JPA `javax.persistence.CascadeType`, so we need to use the Hibernate CascadeType and Cascade annotations for mappings, as shown in above example. Commonly used cascading types as defined in CascadeType enum are:
1.  None: No Cascading, it's not a type but when we don't define any cascading then no operations in parent affects the child.
2.  ALL: Cascades save, delete, update, evict, lock, replicate, merge, persist. Basically everything
3.  SAVE\_UPDATE: Cascades save and update, available only in hibernate.
4.  DELETE: Corresponds to the Hibernate native DELETE action, only in hibernate.
5.  DETATCH, MERGE, PERSIST, REFRESH and REMOVE - for similar operations
6.  LOCK: Corresponds to the Hibernate native LOCK action.
7.  REPLICATE: Corresponds to the Hibernate native REPLICATE action.
  1. 如何在Hibernate应用程序中集成log4j日志记录?

Hibernate 4 uses JBoss logging rather than slf4j used in earlier versions. For log4j configuration, we need to follow below steps.

-   Add log4j dependencies for maven project, if not maven then add corresponding jar files.
-   Create log4j.xml configuration file or log4j.properties file and keep it in the classpath. You can keep file name whatever you want because we will load it in next step.
-   For standalone projects, use static block to configure log4j using `DOMConfigurator` or `PropertyConfigurator`. For web applications, you can use ServletContextListener to configure it.

That's it, our setup is ready. Create `org.apache.log4j.Logger` instance in the java classes and start logging. For complete example code, you should go through [Hibernate log4j example](/community/tutorials/hibernate-log4j-logging) and [Servlet log4j example](/community/tutorials/servlet-jdbc-database-connection-example).
  1. 如何在Hibernate框架中使用应用服务器的JNDI数据源?

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.

```
<property name="hibernate.connection.datasource">java:comp/env/jdbc/MyLocalDB</property>
```

For a complete example, go through [Hibernate JNDI DataSource Example](/community/tutorials/hibernate-tomcat-jndi-datasource-example-tutorial).
  1. 如何集成Hibernate和Spring框架?

Spring is one of the most used Java EE Framework and Hibernate is the most popular ORM framework. That’s why Spring Hibernate combination is used a lot in enterprise applications. The best part with using Spring is that it provides out-of-box integration support for Hibernate with **Spring ORM** module. Following steps are required to integrate Spring and Hibernate frameworks together.

1.  Add hibernate-entitymanager, hibernate-core and spring-orm dependencies.
2.  Create Model classes and corresponding DAO implementations for database operations. Note that DAO classes will use SessionFactory that will be injected by Spring Bean configuration.
3.  If you are using Hibernate 3, you need to configure `org.springframework.orm.hibernate3.LocalSessionFactoryBean` or `org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean` in Spring Bean configuration file. For Hibernate 4, there is single class `org.springframework.orm.hibernate4.LocalSessionFactoryBean` that should be configured.
4.  Note that we don't need to use Hibernate Transaction Management, we can leave it to Spring declarative transaction management using `@Transactional` annotation.

For complete example go through [Spring Hibernate Integration](/community/tutorials/spring-hibernate-integration-example-tutorial) and [Spring MVC Hibernate Integration](/community/tutorials/spring-mvc-hibernate-mysql-integration-crud-example-tutorial).
  1. 什么是HibernateTemplate类?

When Spring and Hibernate integration started, Spring ORM provided two helper classes - `HibernateDaoSupport` and `HibernateTemplate`. The reason to use them was to get the Session from Hibernate and get the benefit of Spring transaction management. However from Hibernate 3.0.1, we can use `SessionFactory` _getCurrentSession()_ method to get the current session and use it to get the spring transaction management benefits. If you go through above examples, you will see how easy it is and that's why we should not use these classes anymore. One other benefit of `HibernateTemplate` was exception translation but that can be achieved easily by using `@Repository` annotation with service classes, shown in above spring mvc example. This is a trick question to judge your knowledge and whether you are aware of recent developments or not.
  1. 如何将Hibernate集成到Servlet或Struts2 Web应用程序中?

Hibernate integration with Servlet or Struts2 needs to be done using `ServletContextListener`, a complete example can be found at [Hibernate Struts2 Integration Example](/community/tutorials/struts2-hibernate-integration-example-tutorial).
  1. 在Hibernate框架中使用了哪些设计模式?

Some of the design patterns used in Hibernate Framework are:
-   Domain Model Pattern - An object model of the domain that incorporates both behavior and data.
-   Data Mapper - A layer of Mappers that moves data between objects and a database while keeping them independent of each other and the mapper itself.
-   [Proxy Pattern](/community/tutorials/proxy-design-pattern) for lazy loading
-   [Factory pattern](/community/tutorials/factory-design-pattern-in-java "Factory Design Pattern in Java") in SessionFactory
  1. 在使用Hibernate框架时有哪些最佳实践?

Some of the best practices to follow in Hibernate are:
-   Always check the primary key field access, if it's generated at the database layer then you should not have a setter for this.
-   By default hibernate set the field values directly, without using setters. So if you want hibernate to use setters, then make sure proper access is defined as `@Access(value=AccessType.PROPERTY)`.
-   If access type is property, make sure annotations are used with getter methods and not setter methods. Avoid mixing of using annotations on both filed and getter methods.
-   Use native sql query only when it can't be done using HQL, such as using database specific feature.
-   If you have to sort the collection, use ordered list rather than sorting it using Collection API.
-   Use named queries wisely, keep it at a single place for easy debugging. Use them for commonly used queries only. For entity specific query, you can keep them in the entity bean itself.
-   For web applications, always try to use JNDI DataSource rather than configuring to create connection in hibernate.
-   Avoid Many-to-Many relationships, it can be easily implemented using bidirectional One-to-Many and Many-to-One relationships.
-   For collections, try to use Lists, maps and sets. Avoid array because you don't get benefit of lazy loading.
-   Do not treat exceptions as recoverable, roll back the Transaction and close the Session. If you do not do this, Hibernate cannot guarantee that in-memory state accurately represents the persistent state.
-   Prefer DAO pattern for exposing the different methods that can be used with entity bean
-   Prefer lazy fetching for associations
  1. Hibernate Validator框架是什么?

Data validation is integral part of any application. You will find data validation at presentation layer with the use of Javascript, then at the server side code before processing it. Also data validation occurs before persisting it, to make sure it follows the correct format. Validation is a cross cutting task, so we should try to keep it apart from our business logic. That’s why JSR303 and JSR349 provides specification for validating a bean by using annotations. Hibernate Validator provides the reference implementation of both these bean validation specs. Read more at [Hibernate Validation Example](/community/tutorials/hibernate-validator-jsr303-example-tutorial).
  1. Hibernate Tools Eclipse插件的好处是什么?

Hibernate Tools plugin helps us in writing hibernate configuration and mapping files easily. The major benefit is the content assist to help us with properties or xml tags to use. It also validates them against the Hibernate DTD files, so we know any mistakes before hand. Learn how to install and use at [Hibernate Tools Eclipse Plugin](/community/tutorials/hibernate-tools-eclipse-plugin).

以上是关于Hibernate面试问题和答案的全部内容,我希望这对您作为应届生或有经验的人参加面试时有所帮助。如果我漏掉了任何重要的问题,请告诉我,我会将其添加到列表中。

Source:
https://www.digitalocean.com/community/tutorials/hibernate-interview-questions-and-answers