【问题标题】:Combine TABLE_PER_CLASS inheritance and TableGenerator结合 TABLE_PER_CLASS 继承和 TableGenerator
【发布时间】:2021-10-02 13:04:32
【问题描述】:

有没有办法让抽象实体的每个子实体的段列值不同,该实体包含在休眠中具有 TABLE_PER_CLASS 继承的 ID 定义?

我有两个从抽象实体扩展而来的实体,如下所示:

@Entity
@GenericGenerator(name = "credentialIdGenerator",
        strategy = "org.hibernate.id.enhanced.TableGenerator",
        parameters = {
                @org.hibernate.annotations.Parameter(name = "value_column_name", value = "GEN_VALUE"),
                @org.hibernate.annotations.Parameter(name = "segment_column_name", value = "GEN_NAME"),
                @org.hibernate.annotations.Parameter(name = "table_name", value = "CORE_CREDENTIAL_ID_GEN"),
                @org.hibernate.annotations.Parameter(name = "prefer_entity_table_as_segment_value", value = "true"),
                @org.hibernate.annotations.Parameter(name = "optimizer", value = "pooled-lo"),
                @org.hibernate.annotations.Parameter(name = "initial_value", value = "50000"),
                @org.hibernate.annotations.Parameter(name = "increment_size", value = "100")})
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Credential implements Serializable {
    @Id 
    @GeneratedValue(generator = "credentialIdGenerator")
    @Column(name = "ID")
    private int id;
}

@Entity
@Table(name = "entity_a")
public class EntityA extends Credential { ... }

@Entity
@Table(name = "entity_b")
public class EntityB extends Credential { ... }

事实上TABLE_PER_CLASS继承策略是最适合我们DB当前架构的策略,事实上目前还没有办法创建新表Credential。 EntityA 和 EntityB 是两个包含很多行的现有表,我需要 Credential 作为实体(而不是 @MappedSuperClass)才能仍然能够拥有 @OneToMany 关系。

当我必须保存这两个实体中的一个新实体时,预期的行为是在我的 CORE_CREDENTIAL_ID_GEN 中为每个实体有不同的行,一个用于 EntityA,另一个用于 EntityB,但结果只是一行具有如下凭据:

+----+------------+-----------+
| id | GEN_NAME   | GEN_VALUE |
+----+------------+-----------+
|  1 | Credential |     50099 |
+----+------------+-----------+

那么有一种配置方法可以使这个生成 id 表具有预期的行为吗?

感谢您的帮助

(我的数据库环境是 MariaDB 10.3)

【问题讨论】:

    标签: java spring hibernate jpa inheritance


    【解决方案1】:

    这是意料之中的。如果您想要不同的 id 空间,则必须分隔实体,即删除超类。 @OneToMany 有什么问题?如果您愿意,可以通过例如引用这两个实体,例如

    @Column(name = "credential_fk")
    Integer credentialFk;
    @OneToMany
    @JoinColumn(name = "credential_fk", insertable = false, updatable = false)
    Set<Entity1> entity1;
    @OneToMany
    @JoinColumn(name = "credential_fk", insertable = false, updatable = false)
    Set<Entity2> entity2;
    

    【讨论】:

    • 事实上,我的抽象实体用于我的核心 Spring 安全逻辑,并与具有 OneToMany 关系的角色以及在 ManyToOne 中与另一个实体相关联。此外,根据 spring 项目,此 Credential 实体是 EntityA 或 EntityB。假设我正在按照您在我的 Role 实体中所说的进行操作,有时 EntityA 和 EntityB 可以具有相同的 id,因此字段 credentailFk 将被复制,您明白我的意思吗? (对不起,我是法国人哈哈)
    • 嗯,你是对的,但是当每个实体都有一个专用(重叠)的 id 空间时,你也会遇到这个问题,所以要么你需要 2 个 FK 来区分这两种类型,要么你坚持到单个 id 空间。
    • 是的,我同意,你认为最好的是什么?
    • 继续使用单个 id 空间 :)
    猜你喜欢
    • 2011-04-03
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 2013-06-02
    • 2016-10-04
    • 2020-07-07
    • 1970-01-01
    • 2011-05-14
    相关资源
    最近更新 更多