2016-07-14 36 views
1

私は、1対1の関係を持つABエンティティを持っています。私はDBにそれらを挿入したいとき、私は次のエラーを取得する:JPAの休止状態での1対1の関係の外部キー制約

Cannot add or update a child row: a foreign key constraint fails (mydb . a , CONSTRAINT FK_77pkrkrin5nqsx16b6nw6k9r7 FOREIGN KEY (id) REFERENCES b (b_id))

@JsonInclude(JsonInclude.Include.NON_NULL)  
@JsonIgnoreProperties(ignoreUnknown = true, value={"hibernateLazyInitializer", "handler"}) 
@Generated("org.jsonschema2pojo") 
@Inheritance(strategy = InheritanceType.JOINED) 
@Entity 
public class A { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @JsonIgnore 
    private Integer id; 

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false) 
    @PrimaryKeyJoinColumn(referencedColumnName="AId") 
    @JsonIgnore 
    private B b; 

} 

@JsonInclude(JsonInclude.Include.NON_NULL) 
@JsonIgnoreProperties(ignoreUnknown = true, value = {"hibernateLazyInitializer", "handler"}) 
@Generated("org.jsonschema2pojo") 
@Entity 
public class B { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private int bId; 

    @OneToOne() 
    @JsonIgnore 
    private A a; 

} 

私はoptional=falseを削除する場合は、挿入操作が完璧に動作します。オブジェクトをDBに挿入する前にオブジェクトをチェックして、ABが、BAが含まれていることを確認しました。

AB作成するためのSQLスクリプトは次のとおりです。Hibernateのドキュメントから

Hibernate: create table b (b_id integer not null auto_increment, string_results longtext, a_id integer, primary key (b_id))

Hibernate: create table a (id integer not null auto_increment, primary key (id))

Hibernate: alter table b add constraint FK_o3oen721etlltdc7ls82524nh foreign key (detail_id) references a (id)

Hibernate: alter table a add constraint FK_77pkrkrin5nqsx16b6nw6k9r7 foreign key (id) references b (b_id)

+0

あなたのデータベースとは何ですか?それはオラクルですか? –

+0

@ArifAcar Google MySQL – hex

+0

あなたのマッピングは正しいですか?エンティティを見ると、両方のテーブルの主キーフィールドは 'BID'と同様に' ID'と呼ばれています。 'B_ID'はマップされていません。まず、正しくマッピングしているかどうかを確認するか、DB作成スクリプトとエンティティの作成と保存を行うコードスニペットを投稿してください。 – ujulu

答えて

0

(Optional) Whether the association is optional. If set to false then a non-null relationship must always exist.

右Bの作成時に、B_IDは使用できません、それはフラッシュがデータベースに発生したときに作成されます。

AはB(b_id)に対して外部キー関係を持つため、この外部関係をオプションとして挿入または挿入する前に、そのIDと共にBを作成する必要があります。

Bを作成してデータベースにフラッシュしてから、Aを作成します。BにAはBの外部キーを定義するAとして必須ではなく、Bの外部キーはAへの参照はAキーを押すと循環参照の問題が発生します。

+0

実際には、BはAに外部キーを持っています。 – hex

+1

「休止状態のドキュメントから:」リンクしてください。 – cobaltduck

+0

https://docs.jboss.org/hibernate/jpa/2.1/api/javax/persistence/OneToOne.html – kuabhina1702

2

私は、次の文を参照する場合:

I checked the objects before inserting them into DB and I make sure that A contains B and B contains A.

私はあなたが双方向の1対1の関係を作成したいという思いを。その場合、現在のマッピングが期待通りに機能しません。私たちはJPA 2.0 spec(ダウンロードリンク)が問題を理解するために、このことについて述べているか見てみましょう:

だから、

Relationships may be bidirectional or unidirectional. A bidirectional relationship has both an owning side and an inverse (non-owning) side. A unidirectional relationship has only an owning side. The owning side of a relationship determines the updates to the relationship in the database, as described in section 3.2.4.

The following rules apply to bidirectional relationships:

• The inverse side of a bidirectional relationship must refer to its owning side by use of the mappedBy element of the OneToOne, OneToMany, or ManyToMany annotation. The mappedBy element designates the property or field in the entity that is the owner of the relationship.

•The many side of one-to-many/many-to-one bidirectional relationships must be the owning side, hence the mappedBy element cannot be specified on the ManyToOne annotation.

• For one-to-one bidirectional relationships, the owning side corresponds to the side that contains the corresponding foreign key.

• For many-to-many bidirectional relationships either side may be the owning side.

、双方向の1対1の関係で仕様に従ってエンティティの一つが所有側を行わなければなりませんもう一方は反対側にあります。

@Entity 
public class A { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Integer id; 

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false) 
    @JoinColumn(name="b_id", referencedColumnName="ID") 
    private B b; 

} 

@Entity 
public class B { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private int id; 

    @OneToOne(mappedBy = "b") 
    private A a; 

} 

上記のマッピング作業を行うためには、物理​​テーブルが自動的に生成されなければならないか、テーブルを自分で作成する場合は、対応するSQL次のいずれかのエンティティAは、以下のマッピングが動作するはず所有側であると仮定しましょう

create table a (id integer not null auto_increment, 
       b_id integer not null, 
       primary key (id), 
       foreign key b_id references b (id)); 

create table b (id integer not null auto_increment, 
       string_results longtext, 
       primary key (id)); 

注:以下になります

  1. を私は、コードショアを作るためにJSON固有の注釈を削除しました

  2. エンティティBを所有側にしたい場合は、それに応じて関係マッピングを調整する必要があります。

  3. @JoinColumn注釈は常に所有側にあります。

  4. 時間の不足のため、私はコードをテストしていません。バグ(特にMySQLの構文)が見つかった場合は、私にコメントを残してください。

関連する問題