迁移到Hibernate4,@Inheritance和@GeneratedValue误解



我升级了我的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'.

在休眠源代码中,我看到如果实体默认将父级休眠放在SINGLE_TABLE继承上,那么在每个查询中它连接 DiscriminatorColumn,但我没有鉴别器列,因为每个类都映射到不同的表。

为了解决这个问题,我在我的实体上放置了这个注释:

@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

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

@GeneratedValue(strategy=GenerationType.TABLE)

但这导致了另一个异常

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

数据库中的所有表都有一个自动增量 ID。所以我不希望休眠会管理它。

我错过了什么吗?

一些解释:

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 不会在启动时创建它。

一些建议:

  • 标识列和继承在你尝试过的时候效果不佳。您可能应该尝试@Inheritance(strategy=InheritanceType.JOINED),因为这将为具有标识列的基类创建一个表,并将其余属性存储在其他表中。

  • 如果上述方法失败,则通过指定 @GeneratedValue(strategy=GenerationType.SEQUENCE) 来使用序列

相关内容

  • 没有找到相关文章

最新更新