GWT 2.0集成中Gilead的Hibernate Lazy初始化异常问题
我在我的项目中使用 GWT 2.0 作为 UI 层。在服务器端,我使用 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 服务上,我使用 UserService,它使用 userDAO 来获取所有用户。
因此,当我从 UsersService 获取所有用户时,返回的用户实体与 Hibernate 会话分离。因此,我不想在从服务获取的 Users 实例上使用 getRoles() 方法。
我想要的只是通过 RPC 服务传输我的用户列表,以便能够通过 GWT 在客户端使用用户的其他信息。
因此,我的主要问题是能够将 Users.roles 中的 PersistentBag 转换为简单列表,以便能够通过 RPC 传输用户。为此,我发现吉利德框架可能是一个解决方案。
为了使用吉利德,我更改了我的域实体。现在,他们扩展了 net.sf.gilead.pojo.gwt.LightEntity 并且尊重 JavaBean 规范。
在服务器上,借助 GwtRpcSpring 框架,我通过 RPC 公开了我的服务 (http://code.google .com/p/gwtrpc-spring/)。该框架有一个建议可以使吉利德集成变得更容易。
我的 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 获得延迟初始化异常用户.角色。
我很失望,因为我认为吉利德会让我序列化我的域实体,即使这些实体包含 PersistentBag。
这不是吉利德的目标之一吗?
那么,有人知道如何配置吉利德(使用 GwtRpcSpring 或其他解决方案)以便能够在没有惰性异常的情况下传输域实体?
预先感谢您的帮助。
西尔万
I use GWT 2.0 as UI layer on my project. On server side, I use Hibernate. For example, this is 2 domains entities that I have :
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;
}
...
}
On my DAO layer, I use UserDAO that extends HibernateDAOSupport from Spring. UserDAO has getAll method to return all of Users.
And on my DAO service, I use UserService that uses userDAO to getAll of Users.
So, when I get all of Users from UsersService, Users entities returned are detached from Hibernate session. For that reason, I don't want to use getRoles() method on Users instance that I get from my service.
What I want is just to transfer my list of Users thanks to a RPC Service to be able to use others informations of Users in client side with GWT.
Thus, my main problem is to be able to convert PersistentBag in Users.roles in simple List to be able to transfer via RPC the Users. To do that, I have seen that Gilead Framework could be a solution.
In order to use Gilead, I have changed my domains entities. Now, they extend net.sf.gilead.pojo.gwt.LightEntity and they respect JavaBean specification.
On server, I expose my services via RPC thanks to GwtRpcSpring framework (http://code.google.com/p/gwtrpc-spring/). This framework has an advice that makes easier Gilead integration.
My applicationContext contains the following configuration for 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>
The code of the the method doBasicProfiling is the following :
@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;
}
With that configuration, when I run my application and I use my RPC Service that gets all of Users, I obtain a lazy initialization exception from Hibernate from Users.roles.
I am disappointed because I thought that Gilead would let me to serialize my domain entities even if these entities contained PersistentBag.
It's not one of the goals of Gilead ?
So, someone would know how to configure Gilead (with GwtRpcSpring or other solution) to be able to transfer domain entities without Lazy exception ?
Thanks by advance for your help.
Sylvain
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
答案很简单 Object retVal = pjp.proceed();
返回普通的 Hibernate 对象,而不是 Gilead 处理的对象。
也许有人知道如何在服务方面实际添加适当的吉利德建议?
Well the answer is simple Object retVal = pjp.proceed();
returnes plain Hibernate object, not Gilead processed object.
Maybe somebody knows how to actually add proper Gilead advice around services?