I'm using Kotlin in a Spring Boot project. I have a @ManyToMany
relationship between Show
and Product
.
Show entity :
@Entity
@Table(name = "shows")
data class Show(
@Id
val id: String,
@ManyToMany(cascade = [PERSIST])
@JoinTable(
name = "shows_products",
joinColumns = [JoinColumn(name = "show_id")],
inverseJoinColumns = [JoinColumn(name = "product_id")],
)
val products: Set<Product> = emptySet(),
)
Product entity :
@Entity
@Table(name = "products")
data class Product(
@Id
val id: String,
@ManyToMany(cascade = [PERSIST], mappedBy = "products")
@JsonBackReference
var shows: Set<Show> = emptySet()
)
I have also created the corresponding repositories.
I want to delete a show
from the DB, without deleting the products
attached to it.
The problem that I've encountered is when I call 'showRepository.delete(show)'.
If that show
doesn't have any products
attached to it, then it's deleted as expected.
But if it has some products attached to it, the show is not deleted, but no exception is thrown. Additionally, the tests of the repository are not catching this :
@Test
fun `delete show with product`() {
productRepository.save(aProduct)
showRepository.save(aShow.copy(products = setOf(aProduct)))
assertThat(showRepository.findByIdOrNull(aShow.id)).isNotNull
assertThat(productRepository.findByIdOrNull(aProduct.id)).isNotNull
showRepository.deleteById(aShow.id)
assertThat(showRepository.findByIdOrNull(aShow.id)).isNull()
}
I did some stackoverflowing, and I found these :
- How to remove entity with ManyToMany relationship in JPA (and corresponding join table rows)?
- JPA - @PreRemove method behaviour
But I still don't understand it and how to implement it, especially if I want to keep the immutability in Kotlin classes.
Also, it started working as expected after removing the product relationship part:
@Entity
@Table(name = "products")
data class Product(
@Id
val id: String,
)
If someone please could help me understand these :
- How to remove an entry properly from a ManyToMany relationship, in both cases, bi and unidirectional ?
- Why no exception was thrown ?
- Why the tests didn't catch what happened in the prod
- How to implement a good solution for this in Kotlin