父表和子表之间的映射不正确

Incorrect mapping between Father and Child tables

我正在尝试在 Spring 数据 JDBC(版本 1.1.5.RELEASE)中建立 Father/Children 关系模型。到目前为止,我已经设法使插入操作正常工作,但在读取数据时遇到错误。

实体看起来像这样

@Table("FATHER")
data class FatherDao(
    @Id
    val id: Long?, 
    @MappedCollection(idColumn="father_id")
    val childrens: Set<ChildrenDao>
)
@Table("CHILDREN")
data class ChildrenDao(
    @Id 
    val id: Long?,
    val father: FatherDao?
)

架构如下:

CREATE TABLE father (
   id INT GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1)
   PRIMARY KEY (id)
);

CREATE TABLE children (
    id INT GENERATED BY DEFAULT AS IDENTITY(START WITH 1, INCREMENT BY 1),
    father_id INT
    PRIMARY KEY (id)
);

现在我已经省略了 character_id 上的外键。

存储库很简单

@Repository
interface FatherRepository : CrudRepository<CharacterDao, Long>

为了保存与父亲关联的子实体,我不调用 ChildrenRepository 而是继续保存父亲实体。

创建很顺利,但是当试图获取创建的实体时,我收到以下异常

user lacks privilege or object not found: FATHER.CHILDREN_DAO in statement [SELECT CHILDREN.id AS id, father.id AS father_id FROM CHILDREN LEFT OUTER JOIN FATHER AS father ON father.children_dao = CHILDREN.id WHERE CHILDREN.father_id = ?]

我的主要问题是我无法理解 FATHER.CHILDREN_DAO 的来源。我相当确定这是由 FatherDao 实体中的错误映射引起的,但即使在 Spring Data JDBC docs 中查看有关集合的信息,我也找不到任何线索。

您似乎试图在 FatherDaoChildrenDao 之间建立双向关系。 Spring 数据 JDBC 不支持此功能。 这两个连接被认为是独立的,Spring 数据 JDBC 尝试加载由 children 引用的父亲,根据映射规则,父亲需要一个 CHILDREN_DAO

根据您的域,有两种变体可以解决问题。 重要的问题是:children 是父亲聚合的一部分还是它们自己的聚合?

如果 children 是父亲聚合的一部分,请删除 father 引用或用 @Transient 标记它。 在后一种情况下,您可以在 FatherDaoAfterLoadCallback

的构造函数中设置值

如果 children 是他们自己的聚合体,则 childrensfather 引用都应该被删除,取而代之的是一个 id(或应使用包含 id 的实体集)。 您可以使用查询方法来加载 child 的父亲,而不是双向关系,反之亦然。

文章 Spring Data JDBC, References, and Aggregates 解释了此设计决策背后的原因,并提供了如何实施的示例。