プロジェクトの UI レイヤーとして GWT 2.0 を使用しています。サーバー側では、Hibernate を使用します。たとえば、これは私が持っている 2 つのドメイン エンティティです。
public class User {
private Collection<Role> roles;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "users", targetEntity = Role.class)
public Collection<Role> getRoles() {
return roles;
}
...
}
public class Role {
private Collection<User> users;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, targetEntity = User.class)
public Collection<User> getUsers() {
return users;
}
...
}
私の DAO 層では、Spring からHibernateDAOSupportを拡張するUserDAOを使用します。UserDAO には、すべてのユーザーを返すgetAllメソッドがあります。
また、私の DAO サービスでは、userDAO を使用してすべてのユーザーを取得するUserServiceを使用しています。
したがって、UsersService からすべてのユーザーを取得すると、返されたユーザー エンティティは Hibernate セッションから切り離されます。そのため、サービスから取得した Users インスタンスでgetRoles()メソッドを使用したくありません。
私が望むのは、RPC サービスのおかげでユーザーのリストを転送して、GWT を使用してクライアント側でユーザーの他の情報を使用できるようにすることです。
したがって、私の主な問題は、Users.roles の PersistentBag を単純なリストに変換して、RPC 経由でユーザーを転送できるようにすることです。そのために、Gilead Framework が解決策になり得ることを私は見てきました。
Gilead を使用するために、ドメイン エンティティを変更しました。現在、これらはnet.sf.gilead.pojo.gwt.LightEntityを拡張し、JavaBean 仕様を尊重しています。
サーバーでは、GwtRpcSpring フレームワーク ( http://code.google.com/p/gwtrpc-spring/ )のおかげで RPC 経由でサービスを公開しています。このフレームワークには、ギリアドの統合を容易にするアドバイスがあります。
私の applicationContext には、 Gilead の次の構成が含まれています。
<bean id="gileadAdapterAdvisor" class="org.gwtrpcspring.gilead.GileadAdapterAdvice" />
<aop:config>
<aop:aspect id="gileadAdapterAspect" ref="gileadAdapterAdvisor">
<aop:pointcut id="gileadPointcut"
expression="execution(public * com.google.gwt.user.client.rpc.RemoteService.*(..))" />
<aop:around method="doBasicProfiling" pointcut-ref="gileadPointcut" />
</aop:aspect>
</aop:config>
<bean id="proxySerializer" class="net.sf.gilead.core.serialization.GwtProxySerialization" />
<bean id="proxyStore" class="net.sf.gilead.core.store.stateless.StatelessProxyStore">
<property name="proxySerializer" ref="proxySerializer" />
</bean>
<bean id="persistenceUtil" class="net.sf.gilead.core.hibernate.HibernateUtil">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean class="net.sf.gilead.core.PersistentBeanManager">
<property name="proxyStore" ref="proxyStore" />
<property name="persistenceUtil" ref="persistenceUtil" />
</bean>
メソッド doBasicProfiling のコードは次のとおりです。
@Around("within(com.google.gwt.user.client.rpc.RemoteService..*)")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
if (log.isDebugEnabled()) {
String className = pjp.getSignature().getDeclaringTypeName();
String methodName = className
.substring(className.lastIndexOf(".") + 1)
+ "." + pjp.getSignature().getName();
log.debug("Wrapping call to " + methodName
+ " for PersistentBeanManager");
}
GileadHelper.parseInputParameters(pjp.getArgs(), beanManager,
RemoteServiceUtil.getThreadLocalSession());
Object retVal = pjp.proceed();
retVal = GileadHelper.parseReturnValue(retVal, beanManager);
return retVal;
}
この構成でアプリケーションを実行し、すべてのユーザーを取得する RPC サービスを使用すると、Hibernate から Users.roles から遅延初期化例外が発生します。
エンティティに PersistentBag が含まれていたとしても、Gilead ではドメイン エンティティをシリアル化できると思っていたので、がっかりしました。
それはギレアデの目標の一つではないのですか?
だから、誰かがギリアドを(GwtRpcSpringまたは他のソリューションで)構成して、Lazy例外なしでドメインエンティティを転送できるようにする方法を知っているでしょうか?
ご協力いただきありがとうございます。
シルヴァン