Hibernate 6.5.0.CR2

发布者:    |       Hibernate ORM 发布

6.5 版本带来了许多新功能,以及许多改进和修复。

Java 时间处理

Java 时间对象现在可以直接通过 JDBC 驱动程序进行序列化,这是由 JDBC 4.2 规定的。在之前的版本中,Hibernate 会使用 java.sql.Datejava.sql.Timejava.sql.Timestamp 引用作为中间形式来处理 Java 时间对象。

与此相关的另一个行为变化是时区处理。 OffsetDateTimeOffsetTimeZonedDateTime 都编码了显式时区信息。在使用直接序列化的情况下,Hibernate 简单地传递原始值。在旧的行为中,由于 java.sql 变体不编码时区信息,Hibernate 通常必须在转换为这些中间形式时特别处理时区。

对于 6.5,此行为默认是禁用的。要启用,

hibernate.type.java_time_use_direct_jdbc=true

请参阅设置 Javadoc 以获取更多详细信息。

尽管此功能自 JDBC 4.2(Java 8)以来就是 JDBC 的一部分,但已知此功能与 Sybase jConnect 驱动程序不兼容。我们已经通知了 Sybase 开发团队,但这种情况似乎不太可能改变。

可配置的查询缓存布局

在 Hibernate ORM 6.0 中,查询缓存布局从实体的“浅”表示形式更改为“完整”表示形式。这样做是为了支持从查询缓存数据中重新实体化联接抓取的数据,而无需击中数据库。将完整数据存储在查询缓存中会导致更高的内存消耗,这反过来可能会因为更高的垃圾收集活动而降低应用程序吞吐量。

6.5 添加了配置查询结果在查询缓存中存储格式的功能,可以是

  • 全局通过 hibernate.cache.query_cache_layout 设置

  • 通过实体或集合的 @QueryCacheLayout 注解

全局设置 hibernate.cache.query_cache_layout 默认为 AUTO 值,将根据实体/集合是否可缓存自动选择 SHALLOWFULL

希望保留 Hibernate ORM 6.0 中使用的 FULL 缓存布局的应用程序应配置全局属性 hibernate.cache.query_cache_layout=FULL。希望使用 Hibernate ORM 5 及更早版本中使用的缓存布局的应用程序应配置全局属性 hibernate.cache.query_cache_layout=SHALLOW

即使在 SHALLOW 缓存布局下,通过连接抓取所暗示的关联渴望将被尊重,并且关联将被积极初始化。因此,在选择不同的缓存布局时,行为不会发生变化。

使用 SHALLOW 时,如果关联数据不在二级缓存中,Hibernate 可能需要访问数据库来具体化这些数据。

允许将 Java 记录用作 @IdClass

现在可以使用 Java 记录作为 @IdClass

record PK(Integer key1, Integer key2) {}

@Entity
@IdClass(PK.class)
class AnEntity {
        @Id Integer key1;
        @Id Integer key2;
        ...
}

支持自动启用的过滤器

现在可以为每个 Session 和 StatelessSession 自动启用过滤器。

@FilterDef(
    name="active-filter",
    condition="status = true",
    autoEnabled=true
)
@Filter(name="active-filter")
@Entity
class DeletableEntity {
    ...
}

可以与动态解析条件参数的能力结合使用,例如。

class TenantIdResolver implements Supplier<String> {
    @Override
    public String get() {
        return SomeContext.determineTenantId();
    }
}

@FilterDef(
    name="tenancy-filter",
    condition="tenant_id = :tenantId",
    autoEnabled=true,
    parameter = @ParamDef(
        name="tenantId",
        type=String.class,
        resolver=TenantIdResolver.class
    )
)
@Filter(name="tenancy-filter")
@Entity
class SensitiveData {
        ...
}

连接突变查询

UPDATE 和 DELETE 查询现在可以使用连接,例如。

delete from Person p where p.association.someAttr = 1

使用自定义 Generator 手动分配标识符

现在可以使用自定义的 Generator 使用手动分配的标识符值,归功于新的 allowAssignedIdentifiers() 方法。

class MyIdGenerator implements Generator {
    ...
    @Override public boolean allowAssignedIdentifiers() {
        return true;
    }
}

@IdGeneratorType(MyIdGenerator.class)
@Target({METHOD, FIELD})
@Retention(RUNTIME)
@interface MyGeneratedId {
}

@Entity
class Book {
  @Id @MyGeneratedId
  Integer id;
  ...
}

Book book = new Book(1,...)
session.persist(book);

SelectionQuery.getResultCount()

选择查询现在能够报告最终结果中将有多少结果。

这会触发对数据库的查询。
Query query = session.createQuery("from Person");
int results = query.getResultCount();

基于键的分页

作为一项孵化特性,6.5 通过 SelectionQuery生成的查询方法 支持基于键的分页(有时称为“键集”分页)。

请参阅 KeyedPageKeyedResultList 的 Javadoc 获取更多信息。

插入查询的 ON CONFLICT 子句

现在,HQL 和 Criteria 都支持可选的 ON CONFLICT 子句,允许在发生约束违规时控制应该发生什么,例如。

insert into Person (id, name)
values (1, 'John')
on conflict do nothing

有关详细信息,请参阅 用户指南

对 StatelessSession 的工作

StatelessSession 现在支持 过滤器SQL 记录

Jakarta Data

6.5 还包括基于 Hibernate 注解处理器的 Jakarta Data 技术预览。


返回顶部