如何组合TABLE_PER_CLASS和GenerationType.IDENTITY

时间:2017-11-23 12:49:00

标签: java mysql spring hibernate persistence

亲爱的未来读者:在完成Sannes answer和他提供的链接之后,我决定改用序列。较新的Hibernates也注意它也适用于MySQL。

我有一个abstract类,其中包含我想要在所有实体中使用的一些基本值(例如id,创建日期,创建用户等)。目前,我正在努力解决每个具体类都有一个表并使其工作的问题。

似乎我可以为每个类创建一个表,也可以在我配置ID的单个位置,但不是两个。这似乎很奇怪,对我来说不太可能,所以我想确保这种情况。

可能相关的版本:hibernate 5,mysql 5.5,java 1.8,spring 4.3。

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@MappedSuperclass
public abstract class GeneralData implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(nullable = false)
    protected int id;
    protected String name;

    // getters, setters, constructors, etc.
}

示例子类:

@Entity
public class ExampleClass extends GeneralData {
    // own values, constructors, getters, setters, etc.
}

我得到错误:

Cannot use identity column key generation with <union-subclass> mapping for: org.example.ExampleClass

我尝试的事情:

  • 我试图让GeneralData成为@Entity,但这并没有帮助。
  • I tried to使用GenerationType.TABLE,但由于密钥太大而失败。 (另外,我不喜欢这个,IDENTITY就是我想要的)错误:Specified key was too long; max key length is 1000 bytes

我宁愿不将id列移动到每个具体类。如果ID仅针对单个表而不是整个依赖关系树,则我完全没问题。

如果我要升级我的库,数据库等,请记住,这样只能通过大量额外工作(由于内部原因)来完成。这将是最后的手段,我希望看到一些证据表明它首先有帮助。

1 个答案:

答案 0 :(得分:-1)

每个具体类映射可以有2个不同的表:

  • 使用隐式多态,不可能使用多态查询,但您可以使用IDENTITY策略(如Sanne所指出的那样效率不高)。标识符可以在超类或子类中定义。
  • 与工会,不允许IDENTITY策略(原因由Sanne清楚解释)。标识符必须在超类
  • 中定义

对于第一个,映射是

@MappedSuperclass
public abstract class GeneralData implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(nullable = false)
    protected int id;
    protected String name;

    ....
}

@Entity
public class ExampleClass extends GeneralData {
    ...
}

而对于第二个,映射是

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class GeneralData implements Serializable {
....
}

@Entity
public class ExampleClass extends GeneralData {
   ...
}