【问题标题】:Micronaut data-jpa - one-to-many - Child entity don't have parent referenceMicronaut data-jpa - 一对多 - 子实体没有父引用
【发布时间】:2021-10-27 15:20:53
【问题描述】:

我正在使用 micronaut-data-hibernate-jpa,并且我有一对多的父子关系。 我正在尝试通过父存储库上的保存操作来保存具有子列表的父实体。父母和孩子被保存,但孩子没有父母ID保存在数据库中。

我的实体是这样定义的:

import java.util.*
import javax.persistence.*

@Entity
data class Parent(
    @Id
    @GeneratedValue
    var id: UUID? = null,
    var name: String,
    @OneToMany(mappedBy = "parent",cascade = [CascadeType.ALL])
    var children: List<Child> = listOf(),
    )
@Entity
data class Child(
    @Id
    @GeneratedValue
    var id: UUID? = null,
    var name: String = "",
    @ManyToOne(fetch = FetchType.EAGER, cascade = [CascadeType.ALL])
    var parent: Parent? = null,
)

使用 CrudRepository 创建存储库

import io.micronaut.data.annotation.Repository
import io.micronaut.data.repository.CrudRepository
import java.util.*

@Repository
interface ParentRepository : CrudRepository<Parent, UUID>

@Repository
interface ChildRepository : CrudRepository<Child, UUID>

我正在使用简单的测试来检查我的设置是否正常,但显然存在问题


import io.micronaut.test.extensions.junit5.annotation.MicronautTest
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

@MicronautTest
class OneToManyTest(
    private val parentRepository: ParentRepository,
    private val childRepository: ChildRepository,
) {

    @BeforeEach
    fun setUp() {
        val childA = Child(name = "Child A")
        val childB = Child(name = "Child B")
        val parentOne = Parent(name = "Parent 1", children = listOf(childA, childB))
        parentRepository.save(parentOne)

        val parentTwo = Parent(name = "Parent 2")
        val childC = Child(name = "Child C", parent = parentTwo)
        childRepository.save(childC)
    }

    @AfterEach
    fun clean() {
        childRepository.deleteAll()
        parentRepository.deleteAll()
    }

    @Test //THIS TEST FAILS
    fun `Parent should have child when saved by parent`() {
        val actual = parentRepository.findAll().toList().filter { it.name == "Parent 1" }[0]

        assertEquals(2, actual.children.size)
    }

    @Test //THIS TEST FAILS
    fun `Child should have parent when saved by parent`() {
        val actual = childRepository.findAll().toList().filter { it.name != "Child C" }

        assertEquals(2, actual.size)  // THIS ASSERT IS OK
        assertNotNull(actual[0].parent)
        assertNotNull(actual[1].parent)
    }

    @Test //THIS TEST IS FINE
    fun `Parent should have child when saved by child`() {
        val actual = parentRepository.findAll().toList().filter { it.name == "Parent 2" }[0]

        assertEquals(1, actual.children.size)
    }

    @Test //THIS TEST IS FINE
    fun `Child should have parent when saved by child`() {
        val actual = childRepository.findAll().toList().filter { it.name == "Child C" }[0]

        assertNotNull(actual.parent)
    }
}

我不知道这是否相关,但我使用 Flyway 生成表格并且我正在使用 postgres

我的迁移脚本:

CREATE
EXTENSION IF NOT EXISTS "uuid-ossp";

CREATE TABLE parent
(
    id   UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
    name CHARACTER VARYING NOT NULL
);

CREATE TABLE child
(
    id        UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
    name      CHARACTER VARYING NOT NULL,
    parent_id UUID REFERENCES parent (id)
)

【问题讨论】:

    标签: hibernate kotlin one-to-many micronaut-data


    【解决方案1】:

    您声明了mappedBy,它定义了谁是关系的所有者,在您的情况下它是孩子,所以您应该在那里分配父母。

    【讨论】:

    • 关系的所有者是Child 实体中的字段parent,这就是为什么它定义为parent(可能不是示例中显示的最佳名称)。除非我错过了什么
    • 好的,我花了一段时间。我用@OneToMany(cascade = [CascadeType.ALL]) @JoinColumn(name = "parent_id") 替换了@OneToMany(mappedBy = "parent",cascade = [CascadeType.ALL]),一切都很好。谢谢。
    猜你喜欢
    • 2018-12-03
    • 2023-03-19
    • 2019-10-01
    • 1970-01-01
    • 2021-10-16
    • 2022-11-29
    • 2013-05-09
    • 1970-01-01
    • 2014-06-03
    相关资源
    最近更新 更多