@SpringBootApplicationclassManyToOneApplication(
val specialItemRepository:SpecialItemRepository,
val regularItemRepository:RegularItemRepository,
val rareItemRepository:RareItemRepository,
val actionRepository:ActionRepository,):CommandLineRunner{
override fun run(vararg args:String?){
kotlin.run {
val regularItem =RegularItem(itemId =11111)
val rareItem =RareItem(itemId =22222)
val specialItem =SpecialItem(itemId =33333)this.regularItemRepository.save(regularItem)this.rareItemRepository.save(rareItem)this.specialItemRepository.save(specialItem)
val action =Action(actionName ="PROCESS")this.actionRepository.save(action)
val ac =this.actionRepository.findById(action.id!!)
ac.stream().forEach {println(it.regularItems.size)}}}}
Ich hätte eigentlich erwartet, dass die gespeicherten Entities in die Action-Entity verbunden werden. Wenn ich diese allerdings über action.regularItems abfrage, wird diese Verknüpfung nicht hergestellt. Die size ist 0. Warum ist das so?
Ich habe gerade realisiert, dass mir noch die Zuweisung bei der Deklaration von Action fehlte:
Java:
@SpringBootApplicationclassManyToOneApplication(
val specialItemRepository:SpecialItemRepository,
val regularItemRepository:RegularItemRepository,
val rareItemRepository:RareItemRepository,
val actionRepository:ActionRepository,):CommandLineRunner{
override fun run(vararg args:String?){
kotlin.run {
val regularItem =RegularItem(itemId =11111)
val rareItem =RareItem(itemId =22222)
val specialItem =SpecialItem(itemId =33333)this.regularItemRepository.save(regularItem)this.rareItemRepository.save(rareItem)this.specialItemRepository.save(specialItem)
val action =Action(
actionName ="PROCESS",
regularItems =listOf(regularItem),
specialItems =listOf(specialItem),
rareItems =listOf(rareItem))this.actionRepository.save(action)
val ac =this.actionRepository.findById(action.id!!)
ac.stream().forEach {println(it.regularItems.size)}}}}
fun main(args:Array<String>){
runApplication<ManyToOneApplication>(*args)}
Nun fliegt das ganze hoch:
Code:
org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.walk.many_to_one.many_to_one.model.RareItem
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:310) ~[spring-orm-6.1.8.jar:6.1.8]
Ich hatte es auch schon mit cascade = [CascadeType.PERSIST] probiert, leider ohne erfolg.
mittlerweile konnte ich die bisherigen Probleme lösen. Ich habe dazu nochmal die Dokumentation gelesen und verstehe, dass die ganzen item-Entitäten die "Owning-Side" der Beziehung sind. Ich wollte die Abfrage auf die jeweiligen Items über die Action durchführen und habe dementsprechend dann auch gemeint ich müsste die items samt der Action instanziieren und persistieren.
Der Code sieht nun so aus:
Java:
@SpringBootApplicationclassManyToOneApplication(
val specialItemRepository:SpecialItemRepository,
val regularItemRepository:RegularItemRepository,
val rareItemRepository:RareItemRepository,
val actionRepository:ActionRepository,):CommandLineRunner{
override fun run(vararg args:String?){
kotlin.run {
val action =Action(
actionName ="PROCESS")this.actionRepository.save(action)
val regularItem =RegularItem(itemId =11111, action = action)
val rareItem =RareItem(itemId =22222, action = action)
val specialItem =SpecialItem(itemId =33333, action = action)this.regularItemRepository.save(regularItem)this.rareItemRepository.save(rareItem)this.specialItemRepository.save(specialItem)}}}
fun main(args:Array<String>){
runApplication<ManyToOneApplication>(*args)}
Kleine korrektur -> targetEntity = RareItem::class ist nicht notwendig bei Verwendung einer mutableList.
Nachdem das Beispiel lauffähig ist frage ich mich, wie ich mit einem Performance-Problem umgehe, wenn ich bspw. sehr viele Actions habe, die bspw. einer weiteren Tabelle hinzugefügt werden und Actions wiederrum sehr große Tabellen der jeweiligen Item-Kategorie.
Ich wollte dazu eine Tabelle anlegen, die eine flache Liste aller itemIds und eine Referenz auf die actionId / actionName hält erstellen, weiß aber noch nicht so recht wie ich das am besten machen könnte. Ratschläge hierzu?
Ich sehe einen Kotlin Code zum ersten Mal, aber wenn ich richtig verstanden habe, dann bringst du in deiner Logik etwas durcheinander. Egal wie viele Items du hast, sie können sich alle auf eine Action Entity beziehen, weil sie durch eine 1:n Beziehung mit ihr verbunden sind.
Du brauchst nur die Getter/Setter-Methoden für deine Items und dann kannst du alle deine Items bei einer Action Entity speichern.
@ExceptionOfExpectation: das letzte Beispiel funktioniert ja, deswegen kann ich dir nicht ganz folgen. Ich muss auch keine getter/setter implementieren, sondern kann direkt auf die Attribute der jeweiligen Item-Klasse zugreifen. In moderneren Java-Versionen ist das ja auch möglich.
Ich habe es mittlerweile Datenbank-seitig gelöst und mir eine View gebaut, die eine flache Liste aller items zur jeweiligen Action bereit hält. Dadurch konnte ich in meinem Fall die Performance drastisch erhöhen. Meine Hibernate-Kenntnisse reichen hier noch nicht aus, aber mittlerweile denke ich ist es besser das DB-seitig zu lösen als mit Programmlogik.
Sorry btw. für die späte Rückmeldung, wollte den Thread hier jedoch nicht als ungelöste Leiche offen lassen.
Kleine korrektur -> targetEntity = RareItem::class ist nicht notwendig bei Verwendung einer mutableList.
Nachdem das Beispiel lauffähig ist frage ich mich, wie ich mit einem Performance-Problem umgehe, wenn ich bspw. sehr viele Actions habe, die bspw. einer weiteren Tabelle hinzugefügt werden und Actions wiederrum sehr große Tabellen der jeweiligen Item-Kategorie.
Ich wollte dazu eine Tabelle anlegen, die eine flache Liste aller itemIds und eine Referenz auf die actionId / actionName hält erstellen, weiß aber noch nicht so recht wie ich das am besten machen könnte. Ratschläge hierzu?
Ich habe deine Frage so verstanden, dass dir nicht ganz bewusst ist, dass die action Entity unendlich viele verschiedene Items speichern kann. Beim genaueren hinschauen, habe ich verstanden, dass es dir um überschaubare Listen geht. Mir war es auch nicht bewusst, dass man von Action Entity aus keine Items zuweisen kann. Was das Getter/Setter angeht, habe ich nur deshalb gesagt, weil ich nicht wusste wie Kotlin mit den Zugriffsmodifikatoren umgeht.