继承:将Super类的@Id注释为具有不同序列的子类

时间:2018-03-20 07:31:25

标签: java hibernate migration hibernate-mapping

我正在将旧项目(Core Java + EJB + hibernate)从hi​​bernate 3迁移到hibernate 5.2.12。虽然hibernate 5.2.12支持.hbm.xml文件,但是作为从.hbm文件迁移到Annotated文件的渐变级别。

以下是我所拥有的场景,数据模型是紧密耦合的类。

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 列表示序列属性,该列使用不同子类的不同序列,尽管所有类都继承了属性id,但每个类使用不同的序列。

对此有任何帮助吗?

2 个答案:

答案 0 :(得分:0)

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

  

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

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

答案 1 :(得分:0)

首先,您必须为BaseClass设置@MappedSuperclass,并使用Fix Generator将@GeneratedValue用作属性ID。 之后,在子类中使用@SequenceGenerator并在BaseClass中使用generator设置name属性。

@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
}