# Hibernate `@NaturalId`示例教程

> 原文： [https://howtodoinjava.com/hibernate/hibernate-naturalid-example-tutorial/](https://howtodoinjava.com/hibernate/hibernate-naturalid-example-tutorial/)

[**Hibernate**](//howtodoinjava.com/hibernate-tutorials/ "hibernate tutorial") 4 带来了许多改进， [**`@NaturalId`**](http://docs.jboss.org/hibernate/orm/4.0/javadocs/org/hibernate/annotations/NaturalId.html "NaturalId")就是这样的改进之一。 如您所知，`@Id`注解用作指定实体主键的元数据。 但是有时，实体通常在 DAO 层代码中使用 ID，该 ID 不是主键，而是其逻辑或自然 ID。 在这种情况下，`@NaturalId`注解将证明是 Hiberate 下命名查询的良好替代。

例如，在任何应用中都可以有一个雇员实体。 在这种情况下，主键肯定是“员工 ID”，但在通过电子邮件登录等情况下，用户将提供电子邮件和密码。 在这种情况下，您可以直接在“电子邮件”字段上使用`@NaturalId`注解，而不必编写命名查询。

## 工作原理

如果您查看日志，那么您会知道，当您通过其自然 ID 获得实体时，

1.  通过执行自然 ID 的`where`子句找到实体的第一个主键
2.  该主键用于获取实体的信息

## 用法示例

让我们来看这个例子。

作为参考，最新的 Hiberate Maven 依赖项如下：

```java
<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-core</artifactId>
	<version>4.3.0.Beta3</version>
</dependency>

```

现在，最小员工实体应如下所示：

**`EmployeeEntity.java`**

```java
@Entity
@Table(name = "Employee", uniqueConstraints = {
		@UniqueConstraint(columnNames = "ID"),
		@UniqueConstraint(columnNames = "EMAIL") })
public class EmployeeEntity implements Serializable {

	private static final long serialVersionUID = -1798070786993154676L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "ID", unique = true, nullable = false)
	private Integer employeeId;

	//Use the natural id annotation here
	@NaturalId (mutable = false)
	@Column(name = "EMAIL", unique = true, nullable = false, length = 100)
	private String email;

	@Column(name = "FIRST_NAME", unique = false, nullable = false, length = 100)
	private String firstName;

	@Column(name = "LAST_NAME", unique = false, nullable = false, length = 100)
	private String lastName;

	//Setters and Getters
}

```

现在，让我们看看如何在代码中使用它：

**`TestHibernate.java`**

```java
public class TestHibernate
{
	public static void main(String[] args) 
	{
		Session session = HibernateUtil.getSessionFactory().openSession();
		session.beginTransaction();

		//Add new Employee object
		EmployeeEntity emp = new EmployeeEntity();
		emp.setEmail("demo-user@mail.com");
		emp.setFirstName("demo");
		emp.setLastName("user");
		//Save entity
		session.save(emp);

		EmployeeEntity empGet = (EmployeeEntity) session.bySimpleNaturalId( EmployeeEntity.class ).load( "demo-user@mail.com" );

		System.out.println(empGet.getFirstName());
		System.out.println(empGet.getLastName());

		session.getTransaction().commit();
		HibernateUtil.shutdown();
	}
}

Output in console:

Hibernate: insert into Employee (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)

Hibernate: select employeeen_.ID as ID1_0_ from Employee employeeen_ where employeeen_.EMAIL=?

Hibernate: select employeeen0_.ID as ID1_0_0_, employeeen0_.EMAIL as EMAIL2_0_0_, employeeen0_.FIRST_NAME as FIRST3_0_0_, employeeen0_.LAST_NAME as LAST4_0_0_ from Employee employeeen0_ where employeeen0_.ID=?

demo
user

```

要下载以上教程的源代码，请单击下面的下载链接。


**祝您学习愉快！**