1

EJB3 を使用してモデル化しているレガシー データベースがあります。データベースは非常に貧弱な状態にあり、DB への挿入方法には異常な制限があります。ここで、DB 構造に適合する階層でデータベースをモデル化したいと考えていますが、永続化マネージャーがエンティティの子を永続化しようとせずに、各エンティティを個別に手動で挿入できるようにしたいと考えています。

私は次のようなことを試みています(ボイラープレートは省略されています):

@Entity
@Table(name = "PARENT_TABLE")
public class Parent {
    @Id
    @Column(name = "ID")
    int id;

    @OneToMany
    List<Child> children;
}


@Entity
@Table(name = "CHILD_TABLE")
public class Child {
    @Id
    @Column(name = "ID")
    int id;   
}

これで例外がスローされます。

java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST

これで、エンティティが PERSIST とマークされていないことがわかりました - EntityManager に永続化させたくありません! 最初に親を永続化し、次に子を永続化できるようにしたいのですが、一緒ではありません。このようにしたいのには十分な理由がありますが、遊びたくないようです。

4

1 に答える 1

6

JPA構成である髪を引っ張るへようこそ。

あなたの場合、2つの選択肢があります:

  1. 新しいオブジェクトを手動で永続化します。また
  2. 自動的に永続化します。

自動的に永続化するには、関係に注釈を付ける必要があります。これは一般的な 1 対多のイディオムです。

@Entity
@Table(name = "PARENT_TABLE")
public class Parent {
  @Id private Long id;

  @OneToMany(mappedBy = "parent", cascade = CascadeType.PERSIST)
  private Collection<Child> children;

  public void addChild(Child child) {
    if (children == null) {
      children = new ArrayList<Child>();
    }
    child.setParent(parent);
    children.add(child);
  }
}

@Entity
@Table(name = "CHILD_TABLE")
public class Child {
  @Id private Long id;

  @ManyToOne
  private Parent parent;

  public void setParent(Parnet parent) {
    this.parent = parent;
  }
}

Parent parent = // build or load parent
Child child = // build child
parent.addChild(child);

カスケード持続のため、これは機能します。

注:自分で Java レベルで関係を管理する必要があるため、手動で親を設定します。これは重要。

それがなければ、オブジェクトを手動で永続化する必要があります。これを行うには EntityManager が必要です。その場合、次のように簡単です。

entityManager.persist(child);

その時点で、それは正しく機能します (他のすべてが機能すると仮定します)。

純粋な子エンティティについては、アノテーション アプローチをお勧めします。それはただ簡単です。

JPAについて言及する1つの落とし穴があります:

Parent parent = new Parent();
entityManager.persist(parent);
Child child = new Child();
parent.addChild(child);

今、私はこれについて少し錆びていますが、子が追加される前に親が永続化されていたため、これを行うと問題が発生する可能性があると思います。何をするにも注意して、このケースを確認してください。

于 2009-02-25T10:35:24.217 に答える