【问题标题】:Inheritance: Annotate @Id of Super class to child class having different sequences继承:将 Super 类的 @Id 注释到具有不同序列的子类
【发布时间】:2018-03-20 07:31:24
【问题描述】:

我正在将旧项目(Core Java + EJB + hibernate)从 hibernate 3 迁移到 hibernate 5.2.12。虽然 hibernate 5.2.12 支持 .hbm.xml 文件,但作为从 .hbm 文件迁移到带注释文件的渐变的一部分。

下面是我的场景,数据模型是紧耦合类。

public interface BaseEntity extends Serializable, Cloneable, Observable
{
    public void setId(long id);

    public long getId();

    ... few other generic attributes
}

public class BaseClass implements BaseEntity {

    protected long id;

    public void setId(long id)
    {
        this.id = id;
    }

    public long getId()
    {
        return objectId;
    }
.. few other attributes
}


public class AuditableBaseClass extends BaseClass implements BaseEntity, Audit
{
    ... few other attributes
}


public class Car extends AuditableBaseClass {
    .... some attributes
}


public class Bike extends AuditableBaseClass {
    ...some attributes
}

public class Truck extends AuditableBaseClass {
    ... some attributes
}

如果我们查看下面现有的 .hbm.xml 文件,对于不同的类使用不同的序列

<class name="Car" table="Car">      
    <id name="id" type="long" column="id">
      <generator class="sequence">
        <param name="sequence">SEQ_CAR</param>      
      </generator>
    </id>
    <
    // some other properties
</class>

<class name="Bike" table="Bike">
    <id name="id" type="long" column="id">
      <generator class="sequence">
        <param name="sequence">SEQ_BIKE</param>         
      </generator>
    </id>
    // some other properties
</class>


<class name="Truck" table="Truck">
    <id name="objectId" type="long" column="id">
      <generator class="sequence">
        <param name="sequence">SEQ_TRUCK</param>        
      </generator>
    </id>
</class>

@Id 使用序列的简单定义如下

@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "sequence-generator" )
@SequenceGenerator( name = "sequence-generator", sequenceName = "SEQ_NAME" )

事实上,我知道我们需要使用@MappedSuperclass 来表示超类。如何表示@Id 列的sequence 属性,该列使用不同子类的不同序列,尽管所有类都继承属性id,但每个类使用不同的序列。

请问有什么帮助吗?

【问题讨论】:

标签: java hibernate migration hibernate-mapping


【解决方案1】:

首先你必须为 BaseClass 设置 @MappedSuperclass 并使用 @GeneratedValue 作为属性 id 和修复生成器。 之后在子类中使用 @SequenceGenerator 并在 BaseClass 中使用生成器设置名称属性。

@MappedSuperclass
public class BaseClass implements BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_seq_gen")
    @Column(name = "ID")
    protected long id;

    public void setId(long id)
    {
        this.id = id;
    }

    public long getId()
    {
        return objectId;
    }
.. few other attributes
}

public class AuditableBaseClass extends BaseClass implements BaseEntity, Audit
{
    ... few other attributes
}

@Entity
@Table(name="car")
@SequenceGenerator(sequenceName = "car_id_seq", allocationSize = 1, name = "my_seq_gen")
public class Car extends AuditableBaseClass {
    .... some attributes
}

@Entity
@Table(name="bike")
@SequenceGenerator(sequenceName = "bike_id_seq", allocationSize = 1, name = "my_seq_gen")
public class Bike extends AuditableBaseClass {
    .... some attributes
}

@Entity
@Table(name="truck")
@SequenceGenerator(sequenceName = "truck_id_seq", allocationSize = 1, name = "my_seq_gen")
public class Truck extends AuditableBaseClass {
    ... some attributes
}

【讨论】:

  • 我有同样的问题,但在我们的系统中,每个表都有不同的序列生成器,@GeneratedValue 中的生成器值不是恒定的。这种情况该怎么办?
【解决方案2】:

Hibernate 5.2 不允许我们拥有两个具有相同名称的标识符生成器,​​即使它们具有不同的配置,因为范围是全局的,如 JPA 规范中所述。因此,您需要在实体类中定义标识符和生成器。

可以在实体类或主键字段或属性上指定序列生成器。生成器名称的范围对于持久性单元是全局的(跨所有生成器类型)。

参考:https://hibernate.atlassian.net/browse/HHH-12329@Vlad Mihalcea

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-25
    • 2020-03-23
    • 2015-10-01
    • 2022-11-18
    • 2011-04-09
    • 2019-03-28
    • 2018-06-25
    • 1970-01-01
    相关资源
    最近更新 更多