【问题标题】:Hibernate subclass id generation in table per subclass在每个子类的表中生成休眠子类 ID
【发布时间】:2014-07-02 11:02:32
【问题描述】:

当我使用 table-per-subclass 策略时,我的基类(父类)包含复合主类。

@Column(nullable = false)
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "XXX")
@SequenceGenerator(name = "XXX", sequenceName = "XXX",  allocationSize = 1)
private Long systemId;

@Id
@Column(nullable = false)
private Long version; 

因此,所有扩展它的实体(据我所知)都继承了 id 及其带注释的属性。 问题是,当我创建一个新的父实体时,主实体是从序列创建的,没关系。但是当我创建子类实例时,它会增加我不需要的父 ID(从 seq 创建一个新的主节点),`因为我使用每个子类的表,并且主节点必须相同。

问题:如何抑制子类中的 id 生成?

@Entity
@PrimaryKeyJoinColumns(
    {
            @PrimaryKeyJoinColumn(name = "systemId"),
            @PrimaryKeyJoinColumn(name = "version")
    }
)
public class SUb extends Parent {

public SUb (Parent t) {
    super(t);
}

public SUb () {
}
...

... no ids...

【问题讨论】:

    标签: java hibernate jpa orm


    【解决方案1】:

    创建子类时,它将发出两个插入:

    1. 基类中的一个
    2. 子类中的一个

    子类不继承@Ids,而是使用:

    • 系统标识
    • 版本

    作为基表关联列的 FK。

    因此,虽然基类有一个由这两列组成的主键:

    • 一个序列生成的systemId
    • 手动分配的版本

    子类应该有:

    • 一个 sequnceId 列,其 FK 指向基本 sequnceId 列
    • 一个带有基本版本列的 FK 的版本列

    因此在插入子类实体时不应调用该序列两次。

    您能否确认数据库表遵循此设计?

    【讨论】:

    • 是的,但我在子类中没有@id`s。休眠甚至不能允许。我的 PrimaryKeyJoinColumns 有 2 列我的复合 PK
    • 我以为第二个来自子类。在这种情况下,分配了第二个列标识符。
    • 请同时发布基类和子类以进一步检查。
    • 它非常大,我想这会是不好的风格。
    • 您说子类应该有一个 sequnceId 列,并带有一个对基本 sequnceId 列的 FK,依此类推。所以在我的情况下,'因为据说每个子类的表子类不使用父字段。我必须隐含地声明它吗?
    【解决方案2】:

    我无法重现您的问题。您能否更具体地说明您的加入策略是什么?是InheritanceType.TABLE_PER_CLASS 还是InheritanceType.JOINED?尽管如此,我还是设法使用 TABLE-PER-CLASS 连接策略准备了完整的示例,当您坚持 SubDepartment 时,它只会增加一次序列。也许有帮助。

    @Entity
    @IdClass(CompoundPK.class)
    @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
    public class Department {
    
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "XXX")
        @SequenceGenerator(name = "XXX", sequenceName = "XXX",  allocationSize = 1)
        @Id
        private Long id;
    
        @Id
        private Long version;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public Long getVersion() {
            return version;
        }
    
        public void setVersion(Long version) {
            this.version = version;
        }
    }
    
    
    @Entity
    public class SubDepartment extends Department {
    
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    public class CompoundPK implements Serializable {
        private Long id;
        private Long version;
    
        public CompoundPK() {
        }
    
        public CompoundPK(Long id, Long version) {
            this.id = id;
            this.version = version;
        }
    
        public Long getId() {
            return id;
        }
    
        public Long getVersion() {
            return version;
        }
    
        // hashCode & equals
    }
    

    【讨论】:

    • InheritanceType.JOINED 策略可以做到这一点吗?以及如何?
    猜你喜欢
    • 2011-12-31
    • 1970-01-01
    • 2011-11-26
    • 2011-12-26
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多