2017-09-06 2 views
1

私はKotlinで書かれた簡単なRESTスプリングブートアプリケーションを持っています。Hibernate OneToMany親からの間違ったバインディング

それは、次のスキーマを持っている:Map hasOneのChannelChannel hasManyのHeaders

私は、コントローラの1つのアクションだけを持っており、このような単一の要求にすべての私のモデルを保存したい:

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

をした場合ヘッダーが設定されていないと、すべてのモデルが正しく関連付けられ、DBの挿入順序も正しくなります。Channelが最初に作成された後、Channel

Mapが作成された後

しかし、私はいくつかのHeaderリストを追加するとき - Hibernateは作るの追加Channel DB内の行とこのチャネルのすべてのHeaderモデルをバインドする(IDを= 2)

マップモデル(ID = 2付き):

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

チャンネルモデル:

... 
@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(), 
... 

ヘッダーモデル:

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

たぶん、いくつかの注釈が固定されなければなりません。助言を聞いてうれしいです。全てに感謝!そのような

UPDATE

保存モデル:

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

UPDATE 2

手動でオブジェクトを作成し、宣言する必要特性がnullableとして入力する場合 - channel_idnull

あろう

私はあなたのHeaderに、あなたは新しいChannelHeaderのインスタンスが作成されるたびに作成しているからだと推測

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) 

答えて

1

アクションにこのコードを追加します。さらに、CascadeTypeALLに設定すると、これは新しく作成されたChannelも永続化されることを意味します。

のタイプをHeaderからChannel?に設定し、後でそれぞれchannelに設定することができます。

編集 コメントからの質問に答えるために:channel_idはあなたがそれぞれのchannelを割り当て、このHeaderを保存した後に自動的に設定されます。

編集2 まず、私は編集モデルをお勧めしたい:

地図:

var channel: Channel? = null 

とヘッダ:

var channel: Channel? = null 

の関連部分をコード:

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

を追加した: 'VARチャンネル:チャンネル? = null'がどのように 'channel_id'をセットしましたか? –

+1

@qwert_ukgこれらのエンティティをどのように保存していますか投稿できますか?その後私は自分の答えを更新する。ありがとう –

+0

は 'チャネル'を割り当てる方法を理解できませんか?私は 'Map'オブジェクトを手動でビルドする必要がありますか? –

0

ANSWER

それはhere

だけのコレクションプロパティからmappedBy = "channel"を削除し、uはそのように意味@JoinColumn(name = "channel_id")

関連する問題