【问题标题】:How to tell JPA to manage dependent entities?如何告诉 JPA 管理依赖实体?
【发布时间】:2020-04-15 16:11:10
【问题描述】:

我的模型有一个典型的父子关系,它是 JPA 建模的,由单向 @OneToMany 关系:
Parent 有 0..n 个 Child 实例(即 List<Child>)。

尝试创建并保留一个 Entity 和一个依赖 Property,如下所示:

val a_parent = Parent(
        id = "I_am_a_parent",
        children = listOf(Child(kind="childish"))
)
parentRepository.save(a_parent)

令人惊讶的结果

org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [parent_id]; nested exception is 
...
Caused by: org.postgresql.util.PSQLException: 
ERROR: null value in column "parent_id" violates not-null constraint
  Detail: Failing row contains (22, childish, null).

在线parentRepository.save(a_parent)

显然,JPA 不会在子级上设置父级的 id(列 children.parent_id)。

为什么不呢?以及如何告诉它这样做?

ParentChild的代码如下

@Entity
@Table(name = "parents")
data class Parent (
        @Id
        @Column(name = "id")
        var id: String? = null,

        @OneToMany(cascade = [CascadeType.ALL], orphanRemoval = true)
        @JoinColumn(name = "parent_id")
        var properties: List<Child> = listOf()
)
@Entity
@Table(name = "children")
data class Child (
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        var id: Int? = null,

        @Column(name = "kind")
        var kind: String? = null
)

【问题讨论】:

  • 为什么要使用可以为空的@Id 列?
  • @AlexRudenko 该列不可为空,属性可以。因为 JPA 需要一个默认的无参数构造函数。 Kotlin 从默认值生成无参数构造函数。我可以将 0 或 -1 作为默认参数,但我更喜欢 null,因为 null 不是 id 的有效值。 - 但是这个话题与问题的错误和问题无关。

标签: java jpa kotlin one-to-many hibernate-onetomany


【解决方案1】:

单向 OneToMany 可能必须以这种方式实现 (reference):

data class Parent (
  //...
    @OneToMany(cascade = [CascadeType.ALL], orphanRemoval = true)
    @JoinColumn(name = "parent_id", nullable = false)
    var properties: List<Child> = listOf()
)

如果数据库列parent_id不可为空,请注意nullable = false

【讨论】:

  • 您提出了双向关系。有许多不同的方式来实现父子关系。我需要一个单向关系。
  • 抱歉,我忽略了这个要求。因此,您的实现似乎非常有效 - 如参考 like this 中所述。但是,在这种情况下,parent_id 列必须可以为空:-\
  • 这是正确的提示。 parent_id 列不需要可以为空。但如果不是,那么我的@JoinColumn 中的nullable=false 是需要的(就像你的答案中给出的那样)。因此,请随意根据单向关系编辑您的答案,我会投票并接受它。
  • 是的。类似问题had happened before
猜你喜欢
  • 2020-04-22
  • 1970-01-01
  • 2018-03-06
  • 1970-01-01
  • 2015-04-18
  • 2019-07-09
  • 2011-12-30
  • 2010-10-28
  • 2019-08-13
相关资源
最近更新 更多