我正在使用Java和Hibernate 3.6.4.Final。
TABLE_B 是特定类型的 A 实体 (B) 的映射表,这些实体与 X 实体具有一对多关系。
我在数据库中插入 B 实体时遇到问题。
从数据库中读取 B 实体不是问题,相关的 X 实体也正确加载。
数据库模型:
- TABLE_A(ID、活动、信息)
- TABLE_B (a_id, x_id)
- TABLE_X(同上,信息)
"A"实体可能与 X 实体有零个或多个关系。
与 X 具有一个或多个关系的"A"实体称为"B"实体,并在代码中具有自己的行为。
(为简单起见,类和表名已更改)
@Entity
@Table(name = "TABLE_A")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class A {
...
}
@Entity
@Table(name="TABLE_B")
@PrimaryKeyJoinColumn(name="A_ID", referencedColumnName = "ID")
public class B extends A implements Serializable {
@OneToMany(cascade={CascadeType.ALL})
@JoinTable(
name="TABLE_B",
joinColumns = @JoinColumn( name="A_ID"),
inverseJoinColumns = @JoinColumn( name="X_ID", insertable = true, nullable = false)
)
private List<X> Xs;
...
}
日志:
SQLStatementLogger - insert into TABLE_A (active, info) values (?, ?)
SQLStatementLogger - insert into TABLE_B (A_ID) values (?)
JDBCExceptionReporter - could not insert: [com.test.B] [insert into TABLE_B (A_ID) values (?)]
java.sql.SQLException: Field 'X_ID' doesn't have a default value
我会理解问题是否是由于将实体表指定为"TABLE_B"并将其用于 OneToMany 连接表引起的,但这就是我的数据库模型的样子。
对我来说,Hibernate似乎首先尝试插入继承,如果可行,下一个插入将是B和X之间的映射。问题是对我来说,继承表和映射表是相同的。
如何在休眠中正确映射数据库模型?非常感谢帮助。
您不能同时将TABLE_B
作为"实体"表(例如B
映射到的表)和"连接"表(例如,保存B
和X
之间的连接的表)。
在第一种情况下,TABLE_B
每条TABLE_A
记录最多需要一条记录(也就是说,对于那些也是B
的A
);在第一种情况下,TABLE_B
需要拥有与B
集合中X
元素一样多的记录,这呈现出明显的矛盾。
因此,您可以执行以下任一操作:
- 映射没有联接表的
Xs
集合(@ManyToOne
在 X 侧;@OneToMany mappedBy="X"
在B侧)。您的"X_TABLE"必须有一个a_id
(或b_id
,无论您怎么称呼它)FK。 - 使用另一个表(
TABLE_B_X
用于B
到X
映射)