次のコードがあります。
public class Parent{
@OneToMany(mappedBy="parent",
targetEntity= Child.class,
fetch = FetchType.LAZY,
cascade= CascadeType.ALL,
orphanRemoval=true)
List<Child> children;
}
public class Child{
@ManyToOne(
targetEntity=Cotizacion.class,
optional=false,
fetch=FetchType.LAZY
)
@JoinColumn(
name = "ID_PARENT",
nullable = false
)
private Parent parent;
}
クライアント側では、GWT エディター フレームワークを使用して親オブジェクト全体を編集しています。
Editor<ParentProxy>
ListEditor<List<ChildProxy>>
同じエディターでオブジェクト全体を編集する必要があるため、親から子を更新してからドライバーを flush() すると、変更が正しく反映されます。
問題。サーバー側では、null として永続化されたバッグとして子コレクションを持つ親を取得します。(すべての子に対して Locator find() メソッドが呼び出されます)。したがって、クライアント側で変更を行った場合、サーバー側に伝播されずにデータベースに反映されます。
注 1.- クライアント側でオブジェクト全体をチェックすると、変更はエディター ドライバーによって行われました。
注 2.- Locator の find() メソッドでオブジェクト全体を取得しようとしましたが、機能しません。
注 3.- リストを RequestContext の他のパラメーターとして送信し、サーバー側 (DAO) ですべての子を更新すると、正しく更新されます。
更新:子に null を追加すると、persistedbag の代わりにサーバー側でリスト全体が取得され、子の更新が発生します。
元。parent.getChilds().add(null);
RequestFactory はどのようにエンティティのデルタ変更を行いますか?
どんな助けでも感謝します。
更新 2:トーマスのソリューション。
クラス (リスナー):
public class HibernateUtil implements ServletContextListener {}
public class AppSessionManager implements Filter {}
休止状態に必要な行:
<property name="current_session_context_class">thread</property>
web.xml 構成:
<!-- Servlet context listerner -->
<listener>
<listener-class>xxx.yyy.server.tools.HibernateUtil</listener-class>
</listener>
<!-- Servlet for filter -->
<filter>
<filter-name>HibernateFilter</filter-name>
<filter-class>xxx.yyy.server.tools.AppSessionManager</filter-class>
</filter>
<filter-mapping>
<filter-name>HibernateFilter</filter-name>
<url-pattern>/gwtRequest</url-pattern>
</filter-mapping>
エンティティロケータ:
public class BaseEntityLocator extends Locator<BaseEntity, Integer> {
/*
* Method to fetch an object and merge the updates
*
* @see com.google.web.bindery.requestfactory.shared.Locator#find(java.lang.Class, java.lang.Object)
*/
@Override
public BaseEntity find(Class<? extends BaseEntity> clazz, Integer id) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
try {
BaseEntity baseEntity = (BaseEntity) session.get(clazz, id);
return baseEntity;
} catch (RuntimeException e) {
throw e;
}
}
...
}
結果?LazyInitializationException や、タイプ 1 対多のリレーションを更新するその他の問題はもうありません。これが他の人に役立つことを願っています。