4

私は3つのエンティティを持っています。それをA、B、Cと呼ばないようにし、IDの組み合わせである複合キーを持つ4番目のものと呼びます。

@Entity
public class A {
    @Id
    @GeneratedValue(generator = "generator")
    private String id;
}

@Entity
public class B {
    @Id
    @GeneratedValue(generator = "generator")
    private String id;
}


@Entity
public class C {
    @Id
    @GeneratedValue(generator = "generator")
    private String id;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "c", fetch = FetchType.LAZY)
    private List<ClassWithCompositeKey> relations = new ArrayList<ClassWithCompositeKey>();

}

@Entity
public class ClassWithCompositeKey {

    @EmbeddedId
    protected CompositeKey compositeKey;

    @JoinColumn(name = "A_ID", insertable = false, updatable = false)
    @ManyToOne(optional = false)
    private A a;

    @JoinColumn(name = "B_ID", insertable = false, updatable = false)
    @ManyToOne(optional = false)
    private B b;

    @JoinColumn(name = "C_ID", insertable = false, updatable = false)
    @ManyToOne(optional = false)
    private C c;

    public ClassWithCompositeKey(A a, B b, C c) {
       this.a = a;
       this.b = b;
       this.c = c;
       this.compositeKey = new CompositeKey(a.getId(),b.getId(),c.getId());
    }

}

@Embeddable
public class CompositeKey {

    @Basic(optional = false)
    @Column(name = "A_ID", columnDefinition = "raw")
    private String aId;
    @Basic(optional = false)
    @Column(name = "B_ID", columnDefinition = "raw")
    private String bId;
    @Basic(optional = false)
    @Column(name = "C_ID", columnDefinition = "raw")
    private String cId;

    public CompositeKey(String aId, String bId, String cId) {
        this.aId = aId;
        this.bId = bId;
        this.cId = cId;
    }
}

次に、保存しようとしているとき:

A a = new A();
B b = new B();
C c = new C();
entityManager.persist(a);
entityManager.persist(b);
//I'm not saving C
ClassWithCompositeKey classWithCompositeKey = new ClassWithCompositeKey(a, b, c);
c.getRelations().add(classWithCompositeKey);
entityManager.persist(c);

例外が発生しています "ConstraintViolationException: Column 'C_ID' cannot be null"

これは、「c」が保存される前にc.idがnullであるためですが、この値はCompositeKeyインスタンスに渡されます。

「c」を保存し、ClassWithCompositeKeyのコレクションを自動的に保存したいと思います。ただし、最初に「c」を保存してから、ClassWithCompositeKeyインスタンスをアタッチして保存する必要があります。1回の「永続的」呼び出しでCとClassWithCompositeKeyをカスケードで保存することは(おそらく他の種類のマッピングを使用して)可能ですか?

4

3 に答える 3

0

おそらく、複合キー フィールドでカスケード オプションを設定して、少なくとも永続操作をカスケードする必要があります。

于 2012-08-16T13:00:54.703 に答える
0

Cで生成された値を取得するのは永続化のときのみです。これが例外を取得する理由です。

hibernate は、挿入操作の後にのみ生成された値を更新するためです。最初に結合列を挿入してから更新します。

上記のシナリオでは、主キーである ClassWithCompositeKey の C_ID にマップされた主キーである c クラスの C_ID があり、明らかな主キーを null にすることはできません。

したがって、外部キー列を使用して ClassWithCompositeKey を再設計してみてください。

于 2012-08-16T12:42:04.760 に答える
0

問題は、ClassWithCompositeKey クラスでいくつかの列を「挿入可能 = false」および「オプション = false」として同時にマークしていることだと思います。

@JoinColumn(name = "A_ID", insertable = false, updatable = false)
@ManyToOne(optional = false)
private A a;

この列さえ必要ありません!! このクラスの a、b、c 列を削除します。必要な場合は、埋め込み ID に既に含まれています。

ClassWithCompositeKey yourClass = ...;
//any initialization code
yourClass.getCompositeKey().getA();
yourClass.getCompositeKey().getB();
yourClass.getCompositeKey().getC();
于 2012-08-16T21:11:15.317 に答える