Home > Enterprise >  Micronaut data-jpa - one-to-many - Child entity don't have parent reference
Micronaut data-jpa - one-to-many - Child entity don't have parent reference

Time:10-29

I'm using micronaut-data-hibernate-jpa and I have one-to-many relation Parent-Children. I'm trying to save parent entity with list of children by save operation on parent repository. Parent and children are saved but child don't have parent id saved in database.

My Entities are defined like this:

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,
)

Repositories are created using 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>

I was using simple test to check if my set up is fine but apparently there is issue


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)
    }
}

I don't know if this is relevant but I use Flyway to generate tables and I'm using postgres

My migration script:

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)
)

CodePudding user response:

You declared mappedBy which defines who is the owner of the relationship, and in your case it’s Child, so you should have the parent assigned there.

  • Related