2017-09-20 6 views
0

を拡張エンティティクラスに@joinedColumn(表)プロパティを設定するときに、私は次のシナリオがあります。Hibernateの例外別entiryクラス

エンティティコマンド:

@Entity 
public class Command { 

@Id 
@GeneratedValue 
private long id; 

@Column(nullable=false) 
private Date timeOfExecution; 

--constructors, getters, setters...-- 

エンティティCmdTestコマンドを拡張します。

@Entity 
@SecondaryTable(name = "CmdTest") 
public class CmdTest extends Command{ 

    @Column(table = "CmdTest", nullable = false) 
    private String testParam; 

    @OneToOne 
    @JoinColumn(table="CmdTest") 
    private Citizen citizen; 

    -- getters, setters, construcotr -- 
} 

エンティティシチズン:

@Entity 
public class Citizen { 

    @Id 
    @GeneratedValue 
    private long id; 

    @Column(nullable=false) 
    private String name; 

    @OneToOne(mappedBy="citizen") 
    private CmdTest cmdTest; 

    -- getters, setters, constructor -- 
} 

ご覧のとおり、CitizenとCmdTestの間に双方向の関係があります。 私は市民を最初に、そしてCmdTestを維持したい。

私はWebサービスを使用してMyBeanのinitTest()メソッドを呼び出しています。 MyBeanは、CitizenインスタンスとCmdTestインスタンスを作成してから、最初に市民を持続させ、次にCmdTestを維持しようとします。私がコメントする場合、私は、CmdTestテーブル内citizen_id外部キーを永続化するためにJPAを伝えるためにしようと市民フィールド上@JoinColumn(表= "CmdTest")を設定することで

public void initTest() { 

    CmdTest cmd = new CmdTest(); 
    cmd.setTestParam("asd"); 
    cmd.setTimeOfExecution(new Date()); 

    Citizen citizen = new Citizen(); 
    citizen.setName("John Doe"); 

    citizen.setCmdTest(cmd); 
    cmd.setCitizen(citizen); 

    em.persist(citizen); 
    em.persist(cmd); 

} 

:ここ

は私initTest()メソッドでありますその行を外しても問題なく動作しますが、コマンドテーブルの中にはcitizen_idという外部キーがあります。

私は@JoinColumn(表=「CmdTest」)を入れたとき、私は次の例外を取得:私は永続コンテキストに過渡CmdTestオブジェクトを入れてCmdTest最初の持続可能性を知っているNot-null property references a transient value - transient instance must be saved before current operation

、その後、市民とそれは動作します。私はそれを試してみました。

しかし、私は知りたいのですが、なぜこれが機能していないのですか? HibernateまたはJPAのバグですか?理由を見つけることができないようです...

答えて

0

cmdインスタンスをデータベースに保存していないうちに、citizenオブジェクトをcmdオブジェクトへの参照で保存しようとしたため、この例外が発生しました。

これは、citizenインスタンスを永続化しようとすると、データベース内のオブジェクトを永続化して管理しているため、データベース内でこの関係を構築しようとするとオブジェクト(cmdidを使用してそれぞれのcmdオブジェクトを検索しますが、見つからないため、cmdが永続化されていないため、例外Not-null property references a transient value - transient instance must be saved before current operationが表示されます。あなたはcitizenオブジェクトを保存しようとする前に、DBにcmdオブジェクトをpersist/saveする必要が

、これはあなたのコードがどうあるべきかです:

public void initTest() { 

    CmdTest cmd = new CmdTest(); 
    cmd.setTestParam("asd"); 
    cmd.setTimeOfExecution(new Date()); 

    Citizen citizen = new Citizen(); 
    citizen.setName("John Doe"); 

    em.persist(cmd); 

    citizen.setCmdTest(cmd); 
    cmd.setCitizen(citizen); 

    em.persist(citizen); 
} 

だから、これはHibernateのバグではありませんが、これはそれが意図しています方法ですオブジェクトを別のtransientpersisitedではなく)にマップすることはできません。

+0

私はそれをそうすることができると知っています。私の全質問を読んでください。しかし、私の@joinColumnアノテーションからtable = "CmdTest"を削除すると、自分のコードが動作することをどう説明しますか?そうすれば、私が最初に何を維持しても問題なく動作します。なぜ私は不思議ですか? – user3362334

+0

@ user3362334これはバグではありません、それは休止状態の仕組みです、私の編集の説明を見てください。 –

+0

再度読んでください。試してみてください。私のコードを取って@ tableから "CmdTest"パラメータを削除する@joinColumnと動作します。理由を説明してください。だから、その場合でも私はまだcmdと市民の間の双方向の関連付けを持っており、それはcmdにマップされている間に市民オブジェクトを保持しています(このシナリオではdbでは親クラスコマンドに代わりに格納されます)働くそして私は執拗な秩序を変えない、私はまだ市民を最初に守る。やってみて。それだけで動作します。なぜ私は理解できないのですか? – user3362334

関連する問題