2017-09-06 1 views
1

Ich habe eine einfache REST Spring Boot App auf Kotlin geschrieben.Hibernate OneToMany falsche Bindung von Eltern

Es hat nächstes Schema: Map hasOne Channel und Channel hasMany Headers

Ich habe nur eine Aktion von Controller und möchte all meine Modelle in einer einzigen Anfrage wie folgt speichern:

{ 
    "channel": { 
     "headers": [ 
      { 
       "name": "Content-Type", 
       "value": "application/json" 
      } 
     ] 
    } 
} 

Wenn Header ist nicht gesetzt, alle Modelle beziehen sich korrekt und DB-Einfügeauftrag ist auch korrekt: Channel erstellt zuerst und nach dem Erstellen eines Map mit diesem Channel

Aber wenn ich etwas Header Liste hinzufügen - Hibernate macht zusätzliche Channel (mit ID = 2) Zeile in DB und binden alle Header Modelle auf diesen Kanal (mit ID = 2)

Karte Modell:

... 
@ManyToOne(cascade = arrayOf(CascadeType.ALL)) 
@JoinColumn(name = "channel_id") 
var channel: Channel = Channel(), 
... 

Kanalmodell:

... 
@OneToMany(mappedBy = "channel", cascade = arrayOf(CascadeType.ALL),) 
var headers: MutableSet<Header> = mutableSetOf(), 
... 
@JsonIgnore 
@OneToMany(mappedBy = "channel", cascade = arrayOf(CascadeType.ALL)) 
var maps: MutableSet<Map> = mutableSetOf(), 
... 

Header-Modell:

... 
@JsonIgnore 
@ManyToOne(cascade = arrayOf(CascadeType.ALL)) 
@JoinColumn(name = "channel_id") 
var channel: Channel = Channel(), 
... 

Vielleicht sollten einige Anmerkung festgelegt werden. Wir freuen uns, Sie zu beraten. Danke für alles!

UPDATE

speichern Modell wie folgt aus:

@PostMapping("/maps") 
fun post(@RequestBody body: Map) = repo.save(body) 

UPDATE 2

Wenn manuell ein Objekt machen, und erklären notwendigen Eigenschaften geben als nullable-channel_id wird null

diesen Code zur Aktion hinzufügen

val channel = Channel(
     ... 
) 

body.channel!!.headers.forEach { 
    val header = Header(
      name = it.name, 
      value = it.value 
    ) 

    channel.headers.add(header) 
} 

val map = Map(
     channel = channel 
) 

return repo.save(map) 

Antwort

1

Ich denke, es ist, weil in Ihrer Header Sie neue Channel jedes Mal, wenn eine Instanz von Header erstellt schaffen wird. Außerdem stellen Sie die CascadeType auf ALL ein, was bedeutet, dass diese neu erstellte Channel auch beibehalten wird.

Sie können die Art der channel in Header zu Channel? gesetzt und die jeweiligen channel danach eingestellt.

bearbeiten Zur Frage Kommentar antworten: channel_id automatisch eingestellt wird, nachdem Sie die entsprechenden channel zuweisen und diese Header speichern.

Edit 2 Zunächst einmal würde ich das Bearbeiten von Modellen vorschlagen:

Karte:

var channel: Channel? = null 

Und Rubrik:

var channel: Channel? = null 

Relevante Teil Code:

val channel = ... // your Channel entity that is already persisted, for example map.channel (if map was saved before) 
val header = Header(..., channel, ...) // create a new Header and set the channel 
channel.headers.add(header) // it's bidirectional 
repo.save(channel) // this should be enough as you have CascadeType.ALL set, so header should be persisted automatically 
+0

u wie das bedeutet: 'var Kanal: Kanal? = null' aber wie setzt man 'channel_id'? –

+1

@qwert_ukg Können Sie bitte posten, wie speichern Sie diese Entitäten? Danach aktualisiere ich meine Antwort. Danke –

+0

kann nicht verstehen, wie man 'channel' zuweist? U soll ich 'Map' Objekt manuell erstellen? –

0

ANTWORT

es here gefunden

nur mappedBy = "channel" aus der Sammlung Eigentum entfernt und fügen @JoinColumn(name = "channel_id")

Verwandte Themen