我升级了我的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) 来使用序列