編集:解決しましたが、今何が違うのかわかりません。誰かが違ったことが起こったことを説明できれば、私はそれをいただければ幸いです。
現在の動作方法は、次のように、子ではなく親のみをマージすることです。
Parent parent = child.getParent();
parent.getChildren().add(child);
getJpaTemplate().merge(parent);
今は機能しているようですが、以前の試みでは機能しなかったのに、なぜこれが機能するのかよくわかりません。
元の試み/質問:
SpringJPAとIndirectSetsに問題があります。以下に定義する2つのエンティティ、親と子があります。新しい子を作成して既存の親にリンクし、すべてをデータベースとWebインターフェイスに反映させようとしているSpringフォームがあります。何が起こっているのかというと、それはデータベースに入れられますが、UIは一致していないようです。
次のようにOneToMany関係で相互にリンクされている2つのエンティティ:
@Entity
@Table(name = "parent", catalog = "myschema", uniqueConstraints = @UniqueConstraint(columnNames = "ChildLinkID"))
public class Parent {
private Integer id;
private String childLinkID;
private Set<Child> children = new HashSet<Child>(0);
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name = "ChildLinkID", unique = true, nullable = false, length = 6)
public String getChildLinkID() {
return this.childLinkID;
}
public void setChildLinkID(String childLinkID) {
this.childLinkID = childLinkID;
}
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "parent")
public Set<Child> getChildren() {
return this.children;
}
public void setChildren(Set<Child> children) {
this.children = children;
}
}
@Entity
@Table(name = "child", catalog = "myschema")
public class Child extends
private Integer id;
private Parent parent;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ChildLinkID", referencedColumnName = "ChildLinkID", nullable = false)
public Parent getParent() {
return this.parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
}
そしてもちろん、それぞれにさまざまなシンプルなプロパティがあります。さて、問題は、Springインターフェースからこれらの単純なプロパティを編集すると、すべてが美しく機能することです。これらのタイプの新しいエンティティを永続化できます。JPATemplateを使用して、たとえばすべての親(getJpaTemplate()。find( "select p from Parent p"))またはIDによる個々のエンティティを検索すると表示されます。別のプロパティ。
私が遭遇している問題は、現在、親のページからのリンクを介して既存の親にリンクされた新しい子を作成しようとしていることです。コントローラーの重要な部分は次のとおりです(わかりやすくするために、ここではJPA fooをコントローラーに配置しました。実際のJpaDaoSupportは実際には別のクラスにあり、適切に階層化されています)。
protected Object formBackingObject(HttpServletRequest request) throws Exception {
String parentArg = request.getParameter("parent");
int parentId = Integer.parseInt(parentArg);
Parent parent = getJpaTemplate().find(Parent.class, parentId);
Child child = new Child();
child.setParent(parent);
NewChildCommand command = new NewChildCommand();
command.setChild(child);
return command;
}
protected ModelAndView onSubmit(Object cmd) throws Exception {
NewChildCommand command = (NewChildCommand)cmd;
Child child = command.getChild();
child.getParent().getChildren().add(child);
getJpaTemplate().merge(child);
return new ModelAndView(new RedirectView(getSuccessView()));
}
私が言ったように、私はフォームに目を通し、子の新しい値を入力することができます-親の詳細は表示されません。コントローラに戻ると、通過して基盤となるデータベースに保存されますが、インターフェイスがそれを反映することはありません。アプリを再起動すると、すべてがそこにあり、適切に入力されます。
これをクリアするために何ができますか?余分なマージを呼び出したり、更新(トランザクション例外が発生した)を試したりしましたが、独自のデータベースアクセスコードを記述するだけでは不十分でした。すべてのクラスに適切なequals()とhashCode()があり、完全なJPAデバッグをオンにして、適切なSQL呼び出しを行っていることを確認し(Childテーブルへの新しい呼び出しを行っていないようです)、ステップ実行しましたデバッガーを介して(予想どおり、すべてIndirectSetsにあり、親の保存と表示の間に、オブジェクトは新しいメモリアドレスを取得します)。私の次のステップは何ですか?