1

我使用 Hibernate 并希望通过其自然标识符查询实体。但是,似乎不可能在子类型上使用自然 id。我有两个类 A 和 B,其中 B 扩展 A:

class A {
  long id;
}

class B extends A {
  String naturalId;
}

A在 Hibernate 中使用自己的标识符进行映射。B被映射为连接的子类。B但是,在 Hibernate 中映射自然标识符是不可能的,因为映射B是子类映射。

  • 为什么不可能在子类上有一个自然标识符B?请注意,我不希望 Hibernate 生成我的数据库模式,我只想拥有自然 id 以实现快速缓存命中。

  • 有没有一种方法/最佳实践可以在子类型上使用自然 id 以进行快速二级缓存查询?

    • 当自然 id 在极少数情况下可能会更新(更改)并且必须在集群 Java EE 环境中维护缓存时,这是否仍然可能?
4

2 回答 2

1
  1. NaturalId 仅对基类有意义,因为没有基类信息就无法检索子类。

    假设您可以使用自然 ID 映射基类和子类:

    class A {
      long id;
      String baseId;
    }
    
    class B extends A {
      String naturalId;
    }
    
    A a = session.bySimpleNaturalId( A.class ).load( "abc" );
    

    如果我们检索的实体是类型 B,则不清楚将使用哪个自然 ID 变体。

  2. 如果不获取基类信息,就无法获取子类。因此,当您从缓存加载子类时,也会检索相关的基类信息。因此,您可以让基类存储自然 ID,或者简单地使用主键进行缓存。

  3. 您可以更新 natural-id,但业务密钥应该是不可变的。对于可变的自然 ID,您需要使用mutable属性。

于 2015-03-11T14:59:43.807 回答
0

根据13.3。实体继承和二级缓存映射

从 Hibernate ORM 5.3 开始,您现在可以在子类级别覆盖基类 @Cacheable 或 @Cache 定义。

所以你可能有机会通过在B.
我从未尝试过,所以请通过评论确认解决方案。

于 2019-06-03T21:19:00.467 回答