在Java持久化API(JPA)中,@Table
注解用于指定实体类与数据库表之间的映射关系。其中一个重要的属性是uniqueConstraints
,它允许我们在表级别定义唯一性约束。本文将通过一个实例,详细探讨如何使用@Table
注解的uniqueConstraints
属性,并展示如何在违反唯一性约束时捕获异常。
@Table注解与UniqueConstraint注解
@Table
注解的uniqueConstraints
属性接收一个UniqueConstraint
数组,每个UniqueConstraint
定义了一个唯一性约束。UniqueConstraint
注解有两个属性:
name
:约束的名称,如果不指定,将由提供者选择一个名称。columnNames
:构成约束的列名数组。
实例演示
首先,我们定义一个Employee
实体类,并在其中使用@Table
注解的uniqueConstraints
属性来定义一个名为uniqueNameConstraint
的唯一性约束,约束字段为name
。
@Entity
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = "name", name = "uniqueNameConstraint")})
public class Employee {
@Id
private long id;
private String name;
private String dept;
// 省略其他字段和方法
}
接下来,我们创建一个ExampleMain
类,用于检查生成的约束并进行数据的持久化和加载。
public class ExampleMain {
private static EntityManagerFactory entityManagerFactory =
Persistence.createEntityManagerFactory("example-unit");
public static void main(String[] args) {
try {
runNativeQuery("SELECT * FROM INFORMATION_SCHEMA.CONSTRAINTS WHERE TABLE_NAME='EMPLOYEE'");
runNativeQuery("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='CONSTRAINTS'");
persistEmployees();
findAllEmployees();
} finally {
entityManagerFactory.close();
}
}
private static void findAllEmployees() {
EntityManager entityManager = entityManagerFactory.createEntityManager();
TypedQuery<Employee> query = entityManager.createQuery("Select e from Employee e", Employee.class);
List<Employee> list = query.getResultList();
list.forEach(System.out::println);
entityManager.close();
}
private static void runNativeQuery(String s) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
Query query = entityManager.createNativeQuery(s);
List list = query.getResultList();
for (Object o : list) {
if (o instanceof Object[]) {
System.out.println(Arrays.toString((Object[]) o));
} else {
System.out.println(o);
}
}
}
public static void persistEmployees() {
Employee employee1 = Employee.of("Diana", "IT");
Employee employee2 = Employee.of("Mike", "Admin");
Employee employee3 = Employee.of("Tim", "Sales");
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
em.persist(employee1);
em.persist(employee2);
em.persist(employee3);
em.getTransaction().commit();
em.close();
}
}
违反唯一性约束
如果我们尝试保存具有相同名称的多个Employee
实体,将抛出ConstraintViolationException
异常。
public class ExampleMain2 {
private static EntityManagerFactory entityManagerFactory =
Persistence.createEntityManagerFactory("example-unit");
public static void main(String[] args) {
try {
persistEmployees();
} finally {
entityManagerFactory.close();
}
}
public static void persistEmployees() {
Employee employee1 = Employee.of("Diana", "IT");
Employee employee2 = Employee.of("Diana", "Admin");
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
em.persist(employee1);
em.persist(employee2);
em.getTransaction().commit();
em.close();
}
}
项目依赖和技术
- h2 1.4.197: H2数据库引擎。
- hibernate-core 5.3.6.Final: Hibernate的核心ORM功能。
- hibernate-jpamodelgen 5.3.6.Final: 注解处理器,用于生成JPA 2静态元模型类。
- JDK 1.8
- Maven 3.5.4
通过上述实例,我们可以看到@Table
注解的uniqueConstraints
属性在定义表级别唯一性约束时的重要作用,以及如何在违反唯一性约束时捕获和处理异常。这有助于我们在设计数据库模型时,确保数据的唯一性和完整性。