0

の2つのエンティティがあります。そして、それらの間には@OneToOneの関係があります。

私は次のクエリを持っています:親pから左結合フェッチp.child

親に存在しない子キー(たとえば-1)を持つ行がある場合、休止状態になり、ケースごとに追加のクエリが発行されます。

Hibernate: 
    select
        parent0_.PARENT_ID as PARENT1_2_0_,
        child1_.CHILD_ID as CHILD1_3_1_,
        parent0_.CHILD_ID as CHILD2_2_0_,
        child1_.NAME as NAME3_1_ 
    from
        PARENT parent0_ 
    left outer join
        CHILD child1_ 
            on parent0_.CHILD_ID=child1_.CHILD_ID
Hibernate: 
    select
        child0_.CHILD_ID as CHILD1_3_0_,
        child0_.NAME as NAME3_0_ 
    from
        CHILD child0_ 
    where
        child0_.CHILD_ID=?

コードは次のとおりです。

@Entity
@Table(name = "PARENT")
public class Parent {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "PARENT_ID", nullable = false)
    private int id;

    @OneToOne(optional = true)
    @JoinColumn(name = "CHILD_ID")
    @NotFound(action = NotFoundAction.IGNORE)
    private Child child;
}

@Entity
@Table(name="CHILD")
public class Child {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "CHILD_ID", nullable = false)
    private int id;

    @Column(name = "NAME")
    private String name;
}

なぜこれが起こるのですか?この余分なSQLを防ぐ方法は?

データベース生成のコードは次のとおりです。

create table PARENT(
PARENT_ID INTEGER GENERATED ALWAYS AS IDENTITY,
CHILD_ID  INTEGER, 
PRIMARY KEY (PARENT_ID)
);

create table CHILD(
CHILD_ID  INTEGER GENERATED ALWAYS AS IDENTITY,
NAME VARCHAR(100) NOT NULL,
PRIMARY KEY (CHILD_ID)
);

insert into PARENT(CHILD_ID) values(-1);
4

2 に答える 2

0

別のフェッチタイプを試す可能性があります。

@OneToOne(optional = true, fetch = FetchType.EAGER)
private Child child;

ただし、JB Nizetがすでに説明しているように、根本的な問題は、CHILD_IDフィールドに格納されている架空の識別子です。

別の戦略は、親クラスの@OneToOneアノテーションにmappedBy属性を追加し、子クラスの親への参照を追加するか、子クラスの親のみを設定することによって、関係を逆転させることです。

于 2012-06-27T11:55:15.290 に答える
0

PARENT.CHILD_IDデータベースを適切に設計し、存在しない子IDを列に格納しないでください。親に子がない場合は、この列にNULLを格納し、列に外部キー制約を作成して、列が常にNULLまたは有効な子IDを保持するようにします。

これにより@NotFound、マッピングから注釈を削除し、追加のクエリを削除できます。実際、Hibernateが最初のクエリを実行すると、子IDとして-1が取得されます。ただし、-1が有効な子IDであるかどうかを知る方法がないため、追加のクエリを実行して、子が存在するか(したがって、親で初期化する必要がある)、存在しないか(したがって、そうでないか)を判断する必要があります。親でnullに設定されます)。

于 2012-06-27T09:48:47.373 に答える