Jpa

Entitymanagerfactory 和 Sessionfactory

1、简介 本文将带你了解 SessionFactory 和 EntityManagerFactory 之间的异同。 顾名思义,这两个类都是用于创建数据库通信对象的工厂类。除了创建对象,它们还提供了其他功能,帮助我们与数据库进行交互。 2、EntityManagerFactory 是什么? Java 持久化 API(JPA)是 Java 应用管理持久化数据的规范。它提供了一种与关系数据库交互的标准方式。EntityManager(实体管理器)作为 JPA 的核心接口,用于与持久化上下文交互并管理实体的生命周期。它为基本的 CRUD 操作提供了具有方法的轻量级实例。 EntityManagerFactory 是一个 JPA 接口,用于创建 EntityManager 实例,以线程安全的方式与持久化上下文(Persistence Context)交互。 2.1、示例 首先,先定义实体: @Entity(name = "persons") public class Person { @Id @GeneratedValue(strategy= GenerationType.IDENTITY) private Integer id; private String name; private String email; // Getter / Setter 省略 } 设置配置有多种方法,这里使用 persistence.xml 配置文件的方法。首先,需要在 resource/META-INF 文件夹中创建该配置文件,并定义连接配置: <persistence-unit name="com.baeldung.sfvsemf.persistence_unit" transaction-type="RESOURCE_LOCAL"> <description>Persistence Unit for SessionFactory vs EntityManagerFactory code example</description> <class>com.baeldung.sfvsemf.entity.Person</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="hibernate.

Jakarta Persistence 3.2 简介

1、简介 Jakarta Persistence(前身为 JPA)是 Java 中对象关系映射的标准 API。它使开发人员能够在 Java 应用中管理关系数据,并通过使用注解和实体类将 Java 对象映射到数据库表来简化数据库交互。 本文将带你了解 Jakarta Persistence 3.2 中引入的一些关键新功能,重点介绍在配置、性能和可用性方面的改进。 2、Jakarta Persistence 3.2 是什么? Jakarta Persistence 3.2 是 Jakarta Persistence API 的最新版本,它为 Java 应用中的对象关系映射(ORM)提供了一种标准化方法。 该版本改进了查询功能、性能和可用性,并增强了对现代数据库功能的支持。 要添加对 Jakarta Persistence 3.2 的支持,必须在 pom.xml 中添加以下 Maven 依赖: <dependency> <groupId>jakarta.persistence</groupId> <artifactId>jakarta.persistence-api</artifactId> <version>3.2.0</version> </dependency> 此外,还需要支持该 API 的最新 Hibernate 7 版本: <dependency> <groupId>org.hibernate.orm</groupId> <artifactId>hibernate-core</artifactId> <version>7.0.0.Beta1</version> </dependency> 3、关键的新功能 Jakarta Persistence 3.2 引入了一些新功能,以改进数据库连接处理、模式配置和事务管理。 3.1、持久化配置 最新的 Jakarta Persistence 3.2 版本添加了编程式 API,可使用 PersistenceConfiguration 类而不是传统的 persistence.

JPA 中的 CAST 和 TREAT

1、简介 在 JPA 中,CAST 和 TREAT 是两个不同的关键字,用于操作数据类型和实体关系。本文将带你了解 CAST 和 TREAT 的区别,并通过示例来说明它们的用法。 2、JPA 中的 CAST JPA 中的 CAST 操作符主要用于 JPQL 查询中的类型转换。它允许我们显式地将一个值从一种数据类型转换为另一种数据类型。例如,可以使用 CAST 将字符串转换为整数,反之亦然。 CAST 的语法如下: CAST(expression AS type) expression 是我们要转换的值或字段,type 是我们要将表达式转换为的目标数据类型。 3、JPA 中的 TREAT 相比之下,TREAT 操作符是为在 JPQL 查询中对实体进行类型安全的向下转换而设计的。它在处理继承层次结构时特别有用。使用 TREAT 时,我们指定实体的子类型,然后 JPA 会检查实际实体是否确实属于该类型。 与 CAST 不同,TREAT 不会改变值的底层数据类型。相反,它允许我们像访问目标类型的值一样访问该值。 TREAT 的语法如下: TREAT(expression AS type) expression 是要处理的值,type 是目标数据类型。 4、适用场景和用法 在 JPA 查询中,CAST 和 TREAT 都用于处理类型转换,但它们的用途不同。 4.1、CAST 操作符 CAST 用于将一种数据类型转换为另一种数据类型,以便进行操作或比较。在执行查询时,如果需要的数据类型与数据库中存储的数据类型不同,通常会使用 CAST。 示例如下:一个名为 Employee 的实体,其 salary 字段在数据库中存储为字符串。下面是 Employee 实体的定义:

JPA 异常 “Could Not Determine Recommended JdbcType for Class”

1、简介 本文将带你了解使用 Hibernate 时出现 “could not determine recommended JdbcType for class” 异常的原因,以及解决办法。 2、常见原因 出现该异常,通常是因为 JPA(Java Persistence API)抛出了异常。 这种情况发生在 JPA 无法确定类的推荐 JDBC 类型时。 通常,这会 Hibernate 应用启动期间发生,当 Hibernate 尝试创建数据库 Schema 或验证映射时。 3、复合数据类型 JPA 中出现 “could not determine recommended JdbcType for class” 错误的一个常见原因是,我们在实体类中使用了复合数据类型或其他非原始类型。一个典型的例子就是使用 java.util.Map 来存储动态键值对。 来看看下面这个实体类: @Entity public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; // 使用了 Map private Map<String, String> studentDetails; // Getter/Setter 省略 } 在上例中,studentDetails 字段是 Map<String, String>。JPA 可能会抛出错误,因为它无法自动为这种复杂的数据类型确定推荐的 JDBC 类型。

解决 JPA 中的 PostgreSQL JSON 类型不匹配异常

1、简介 本文将带你了解在使用 JPA 与 PostgreSQL 交互时出现异常 “PSQLException error: column is of type json but the expression is of type character varying” 的原因,以及解决办法。 2、常见的原因 在 PostgreSQL 中,JSON 或 JSONB 数据类型用于存储 JSON 数据。但是,如果我们试图将字符串(character varyin)插入到期望使用 JSON 的列中,PostgreSQL 就会抛出 “column is of type json but expression is of type character varying” 错误。这种情况在使用 JPA 和 PostgreSQL 时尤其常见,因为 JPA 可能会尝试将字符串保存到 JSON 列,从而导致此错误。 3、异常演示 创建一个基本的 Spring Boot 项目,在 Maven pom.xml 文件中添加 PostgreSQL 依赖: <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.7.1</version> <scope>runtime</scope> </dependency> 创建一个映射到 student 表的 JPA 实体类:

Java 枚举、JPA 和 PostgreSQL 枚举

1、简介 本文将带你了解 Java 枚举、JPA 和 PostgreSQL 枚举的概念,以及如何将它们结合使用,在 Java 枚举和 PostgreSQL 枚举之间创建无缝映射。 2、Java 枚举 Java 枚举(Enum)是一种特殊类型的类,用于表示一组固定数量的常量。枚举用于定义一组具有底层类型(如字符串或整数)的命名值。当我们需要定义一组在应用中具有特定含义的命名值时,枚举非常有用。 下面是一个 Java 枚举的示例: public enum OrderStatus { PENDING, IN_PROGRESS, COMPLETED, CANCELED } 在本例中,OrderStatus 枚举定义了四个常量。这些常量可以在我们的应用中用来表示订单的状态。 3、使用 @Enumerated 注解 在 JPA 中使用 Java 枚举时,需要用 @Enumerated 来注解枚举字段,以指定如何将枚举值存储到数据库中。 首先,定义一个名为 CustomerOrder 的实体类,并用 @Entity 进行注解,以标记其用于 JPA 持久化: @Entity public class CustomerOrder { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Enumerated() private OrderStatus status; // 其他的字段和方法省略 } 默认情况下,JPA 将枚举值存储为整数(Integer),代表枚举常量的序号位置(ordinal())。例如,上文中的 OrderStatus 枚举值 PENDING、IN_PROGRESS、COMPLETED 和 CANCELED,默认行为将分别把它们存储为整数 0、1、2 和 3。由此产生的数据库表将有一个小 int 类型的状态列,其值为 0 至 3:

在 JPA 中使用 CriteriaQuery 执行 COUNT 查询

1、简介 Java Persistence API(JPA)是一种广泛使用的规范,用于访问、持久化和管理 Java 对象与关系数据库之间的数据。JPA 应用中的一项常见任务是计算符合特定条件的实体数量。使用 JPA 提供的 CriteriaQuery API 可以高效地完成这项任务。 CriteriaQuery 的核心组件是 CriteriaBuilder 和 CriteriaQuery 接口。CriteriaBuilder 是创建各种查询元素(如 Predicate、表达式和 CriteriaQuery)的工厂。而,CriteriaQuery 代表一个查询对象,它封装了 select、filter 和 order 标准。 本文将带你了解 JPA 中的 COUNT 查询,学习如何利用 CriteriaQuery API 轻松高效地执行 COUNT 操作。 本文以一个简单的图书管理系统为例,介绍如何利用 CriteriaQuery API 生成各种场景下的图书 COUNT 查询。 2、依赖 创建示例项目。 添加所需的 maven 依赖,包括 spring-data-jpa、spring-boot-starter-test 和 h2 内存数据库: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> 依赖添加完成后,创建图书管理系统示例。它允许我们执行各种查询,如统计所有图书,统计某个作者、书名和年份的图书的各种组合。 添加一个 Book (图书)实体,包含了 title、author、category 和 year 字段:

清除 JPA/Hibernate 中托管的实体

1、概览 本文将带你了解 JPA 是如何托管实体的,以及 Persistence Context(持久化上下文)由于外部变化而无法返回最新数据的情况。 2、Persistence Context 每个 EntityManager 都与一个 Persistence Context 相关联,该上下文在内存中存储所管理的实体。每当通过 EntityManager 对实体执行任何数据操作时,该实体就会变成由 Persistence Context 管理的实体。 当再次检索实体时,JPA 会从 Persistence Context 返回托管实体,而不是从数据库中获取。这种缓存机制有助于提高性能,而无需从数据库中重复获取相同的数据。 Persistence Context 在 JPA 中也被称为一级(first-level,L1)缓存。 3、Demo 设置 首先,创建一个简单的实体类: @Entity @Table(name = "person") public class Person { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; // 构造函数、Getter、Setter 方法省略 } 接下来,创建一个 Person 实体并将其持久化到数据库中: EntityTransaction transaction = entityManager.getTransaction(); transaction.begin(); Person person = new Person(); person.setName("David Jones"); entityManager.persist(person); transaction.

JPA 中实体的继承与组合

1、简介 继承(Inheritance)和组合(Composition)是面向对象编程(OOP)中的两个基本概念,我们也可以在 JPA 中利用它们进行数据建模。在 JPA 中,继承和组合都是对实体间关系进行建模的技术,但它们代表的是不同类型的关系。本文将带你了解这两种方法及其影响。 2、JPA 中的继承 继承是一种 “is-a” 关系,即子类继承超类的属性和行为。这允许子类从超类继承属性和方法,从而促进了代码的重用。JPA 提供了几种策略来模拟实体与其对应的数据库表之间的继承关系。 2.1、单表继承(STI) 单表继承(Single Table Inheritance,STI)将所有子类映射到单个数据库表中。通过利用 区分列 来区分子类实例,这简化了 Schema 管理和查询执行过程。 首先,使用 @Entity 注解将 Employee 实体类定义为超类。接下来,将继承策略设置为 InheritanceType.SINGLE_TABLE,这样所有子类都会映射到同一个数据库表*。 然后,使用 @DiscriminatorColumn 注解来指定 Employee 类中的 区分列。该列用于区分单个表中不同类型的实体。 示例如下,使用 name = "employee_type" 将列名称指定为 employee_type,并使用 discriminatorType = DiscriminatorType.STRING 表示列包含字符串值: @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "employee_type", discriminatorType = DiscriminatorType.STRING) public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; // Get / Set 方法省略 } 对于每个子类,使用 @DiscriminatorValue 注解来指定与该子类相对应的 区别列 的值。在本例中,我们使用 manager 和 developer 分别作为 Manager 和 Developer 子类的 区别值:

JPA 中的 PersistenceUnit 和 PersistenceContext

1、概览 Persistence Context(持久化上下文)和 Persistence Unit(持久化单元)是 JPA 中的两个重要概念,用来管理应用中实体的生命周期。 本文将带你了解 JPA 中的 EntityManager(实体管理器) 的作用,以及 Persistence Context 和 Persistence Unit 的重要性和用例。 2、EntityManager 和 EntityManagerFactory 首先来看看 EntityManager 和 EntityManagerFactory 接口,它们在管理持久性(Persistence)、实体和数据库交互方面发挥着重要作用。 2.1、EntityManager EntityManager 是一个与 Persistence Context 交互的接口。它对实体执行 CRUD 操作、跟踪更改并确保在事务提交时与数据库同步。EntityManager 代表一个 Persistence Context,并在事务范围内运行。 2.2、EntityManagerFactory EntityManagerFactory 是一个创建 EntityManager 的接口,有效地发挥着工厂的作用。创建时,EntityManagerFactory 会与特定的 Persistence Unit 关联,从而创建 EntityManager 的实例。 3、PersistenceContext PersistenceContext 是一个短暂的、事务范围的上下文,用于管理实体的生命周期。它代表一组存储在内存中的 “托管实体”,是实体管理器的一级缓存。如果事务开始,就会创建持久化上下文,并最终在事务提交或回滚时关闭或清除。 持久化上下文会自动检测对托管实体所做的更改,并确保所有实体更改与持久化存储(Persistence Storage)同步。 我们可以使用 @PersistenceContext 注解定义持久化上下文(Persistence Context)的类型: @PersistenceContext private EntityManager entityManager; JPA 中有两种持久化上下文: TRANSACTION 和 EXTENDED。 首先,使用 @Entity 注解创建与 PRODUCT 表相对应的实体: