2012-02-28 6 views
12

を保存するために失敗した@ManyToOneマッピングは、親ID私はEclipseLinkの実装とJPA2を使用してい

![シンプルなテーブル構造] [1]ここで

私はマップしようと2つの表がありますJPA注釈。

public class Story implements Serializable{ 
    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE) 
    Integer id; 
    @Temporal(TemporalType.TIMESTAMP) 
    @Column (name="DATE_CREATED") 
    Date dateCreated; 
    String title; 
    String description; 
    @Column(name="AUTHOR_ID") 
    Integer authorId; 
    @Column(name="COUNTRY_ID") 
    Integer countryId; 
    private String reviews; 

    @OneToMany(mappedBy = "story", cascade=CascadeType.ALL) 
    private List<Tip> tipList; 
} 

public class Tip implements Serializable{ 
    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE) 
    private Integer id; 
    private String description; 
    private Integer vote; 

    @ManyToOne (cascade=CascadeType.ALL) 
    @JoinColumn(name="STORY_ID", referencedColumnName="ID") 
    private Story story; 
} 

単純な例として、同じトランザクションでストーリーといくつかのストーリー関連のヒントを永続化したいとします。

Story newStory = new Story(title, body, ...); 

EntityTransaction transaction = em.getTransaction().begin(); 
    boolean completed = storyService.create(newStory); 
    //The tips are saved as a List<String>. This methods creates the needed List<Tip> from the Strings 
    List<Tip> tips = TipUtil.getTipList(tipList); 
    newStory.setTipList(tips) 
transaction.commit(); 

が、私はエラーがなく、すべてのエンティティがデータベースに永続化されています。ここでは がいることを行うコードのセクションです。問題は、ヒントテーブルstory_idフィールドが常にNULLであることです。私は、JPAがストーリーテーブルから新しいidを得ることができないと想像することができます。ここで正しいアプローチは何ですか?コードの現在の状態で

LE

Tipエンティティが永続化が、国のIDがnullのままされています。

答えて

6

JPAでは、双方向の関係を双方向で更新することが常に推奨されます。これは、データがアプリケーション層で一貫しており、データベースとは何の関係もないことを保証するためです。

ただし、双方向関係で関係の所有側を更新することが必須です。だから、

、あなた次第です

story.setTipList(tips) 

を設定しない/設定。しかし、あなたは変更がDBに適切に反映したい場合は、あなたがTipとして

tip.setStory(story) 

を呼び出すドロドロあなたのコードごとに、ここでは所有側です。 あなたのコードも私には不完全です。理由は、storyService.create(newStory)によって返さ

  • エンティティはnewStory管理していないがされています。だからちょうどnewStory.setTipList(tips)を設定すると、データベースが更新されません
5

子供のそれぞれの親リンクのストーリーを更新する必要があるためです。

StoryクラスにaddTip(ヒントチップ)メソッドを作成する方法です。

この方法はありません:

tip.setStory(this); 
tipList.add(tip); 

あなたがbedirectionalアプローチを必要としない場合は、あなたがヒントに物語のフィールドを削除することができ、それはあなただけで、PrimaryKeyJoinColumnを使用すべきではない、あなたの問題

+1

もっと自動化された方法がないのでしょうか?さらに、Tipのストーリーフィールドを削除することはスマートなアイデアだとは思っていません。この方法では、@PrimaryKeyJoinColumn(name = "STORY_ID"、referencedColumnName = "ID" )、JPAにはどのようにして参加させるべきかという手がかりはない。これはちょっとだけ私の主題を少し読んで理解したものです。私が間違っている場合は教えてください。 – Dragos

+0

Ebeanには自動解決策がありますが、JPAの実装では自動解決策が提供されていません。 – Palesz

0

を解決しますJoinColumn、しかし、あなたの完全なクラスを持つことは、特定の答えを与えるのに役立ちます。

PrimaryKeyJoinColumnは、story_idがヒントのID(ヒントのIDなし)であり、基本的なマッピングが重複していた場合にのみ使用されます。重複したidマッピングはもはや必要ではないので、JPA 2.0ではこれを使用することはほとんどありません。

+0

こんにちは!あなたのお返事ありがとうございます!私は私の質問を更新しました。 '@ PrimaryKeyJoinColumn'アノテーションを変更した後に行われたすべてのエンティティ属性と変更を追加しました。今はっきりしていることを願っています。 – Ionut

1

@Column(名前= "STORY_ID") プライベート整数storyIdを削除します。

あなたは既に@JoinColumnでそれを宣言している(名前は=「STORY_ID」、referencedColumnNameとは=「ID」)

あなたは、複数の書き込み可能なマッピングが[tip.STORY_ID]

フィールドのために存在するエラーを取得している理由であります
+0

ありがとう!実際には他のエラーはありませんが、「ヒント」エンティティはそれ以上永続化されません – Ionut

+0

実装に応じて、双方向の関係では、両方の関係を設定する必要があります(eclipselinkの場合はそうかもしれませんが、試してみる価値がある)。したがって、リストのヒントの各ヒントにnewStoryを設定してみてください。さらに、 "boolean completed = storyService.create(newStory);"という行は、それはtransaction.commitの直前に配置する方がより論理的です。 – Pau

関連する問題