当前位置: 首页 > 知识库问答 >
问题:

迁移到Hibernate 4、@继承和@GeneratedValue误解

陶胤运
2023-03-14

我将web应用程序升级为使用Hibernate 4。在那之后,我遇到了一些问题,我需要帮助。

我有一个域对象的基类,如下所示:

@MappedSuperclass 
public class BaseDomainObject implements Serializable {

    @Id
    @GeneratedValue
    @Column
    protected Integer id;

    public Integer getId() {
            return id;
    }

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

然后,我有很多实体,比如:

@Entity
@Table(name="[user]")
public class User extends BaseDomainObject {

    @Column(name="first_name")
    private String      firstName;
    @Column(name="last_name")
    private String      lastName;

    ....
}

我在实体之间有一些继承:

@Entity
@Table(name="record_data")
@Polymorphism(type=PolymorphismType.EXPLICIT)
public class RecordData extends BaseDomainObject {
    ....
}


@Entity
@Table(name="auto_data")
@Polymorphism(type=PolymorphismType.EXPLICIT)
public class AutoData extends RecordData {

}

当我进行hql查询时,我得到了这个异常

 Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Invalid column name 'DTYPE'.

在hibernate源代码中,我看到,如果实体的父级hibernate在默认情况下处于SINGLE\u表继承状态,那么在每个查询中,它将连接鉴别器列,但我没有鉴别器列,因为每个类都映射到不同的表。

为了解决此问题,我在实体上添加了此注释:

@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) 

但在那之后我又有了一次经历

Caused by: org.hibernate.MappingException: Cannot use identity column key generation with <union-subclass> mapping for: bla.bla.RecordData

我在Web中找到了解决方案。它需要将我的BaseDomainObject中的@GeneratedValue策略更改为TABLE

@GeneratedValue(strategy=GenerationType.TABLE)

但这导致了另一个例外

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name 'hibernate_sequences'.

my DB中的所有表都有一个自动递增id。。所以我不想让hibernate管理它。。

我错过什么了吗?

共有1个答案

晏永康
2023-03-14

一些解释:

Caused by: org.hibernate.MappingException: Cannot use identity column
key generation with <union-subclass> mapping for: bla.bla.RecordData

原因是,如果您在多个表中继承了实体,则无法使用标识列来生成键(因为这可能会在不同的列中生成相同的键)。试想一下,如果您试图检索查询中的所有BaseDomainObjects,那么就不可能以这种方式拥有不冲突的主键。

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Invalid object name
'hibernate_sequences'.

您已将ID生成策略设置为TABLE,但由于某种原因,hibernate没有创建一个表来存储这些ID。您需要手动创建它或找出为什么hibernate不在启动时创建它。

一些建议:

>

  • 标识列和继承并没有像您尝试的那样好用。您可能应该尝试@继承(strategy=InheritanceType.JOINED),因为这将为基类创建一个带有标识列的表,并将其余属性存储在其他表中。

    如果上述失败,请通过指定@GeneratedValue(策略=GenerationType. SEQUENCE)使用序列

  •  类似资料:
    • 从标准 JPA (EclipseLink) 迁移到Hibernate时,由于子记录数量不正确和/或子对象的类型无效,测试失败。我认为问题是Hibernate生成的 SQL 没有在InheritanceType.SINGLE_TABLE关系的 where 子句中使用鉴别器列。 关于在映射中更改什么的任何建议? 提前感谢, 蒂莫西 环境 < li>postgres 9.6.17 < li >Sprin

    • FAQs in section [24]: [24.1] 如何表示“私有继承”? [24.2] 私有继承和组合(composition)有什么类似? [24.3] 我应该选谁:组合还是私有继承? [24.4] 从私有继承类到父类需要指针类型转换吗? [24.5] 保护继承和私有继承的关系是什么? [24.6] 私有继承和保护继承的访问规则是什么? 24.1 如何表示“私有继承”? 用 : priv

    • 问题内容: 我正在尝试将应用程序从Hibernate 3.4.0.GA迁移到Hibernate 5.1,并在完成对Java代码的必要更改后,在部署该应用程序时,我正在观察Hibernate如何尝试 创建HT_表 (全局临时 表 ) ,每个 @Inheritance带 注释的实体一个。 在Google上搜索后,我找到了创建表的原因。 但就我而言,我们不允许更改数据库以添加新表。 我的继承模型只有一层

    • 当我尝试使用将android项目迁移到时,我收到一条错误消息。 错误信息 目前,以下库正在使用。 莫西 刀柄 房间 <代码>构建。渐变 有关更多详细信息,回购托管在此处-https://github.com/Abhimanyu14/finance-manager

    • Angular 是使用 TypeScript 构建的,并且支持向 Angular 提供元信息的装饰器。 TypeScript 的装饰器会让语法感觉更加“自然”,尽管有可能使用 Angular 没有的功能。

    • 在面向对象的程序设计中,定义一个新的 class 的时候,可以从某个现有的 class 继承,新的 class 称为子类,而被继承的 class 称为基类、父类或超类。 Python 中继承的语法如下: class Parent: pass class Child(Parent): pass 在第 1 行,定义了父类 Parent; 在第 4 行,定义了子类 Child,语法