【发布时间】:2012-07-27 13:41:58
【问题描述】:
我确实有问题,但我不知道会发生什么... GWT 初学者,从事个人项目。
环境:
-
maven 项目,包含两个模块
一个模块是'model',具有Hibernate、HSQLDB和Spring依赖. HSQLDB 运行嵌入式,在内存中,从 spring applicationContext.xml 配置
另一个模块是“网络”,并具有所有 GWT 依赖项
该应用程序是使用一些 Spring Roo 生成的代码作为基础构建的,随后进行了修改和扩展。
问题是,当编辑某些实体字段并按下保存时,什么也没有发生。创建新实体实例时没有问题,仅在编辑时更改某些字段并按“保存”基本上会覆盖新值。 所以我开始彻底调试客户端代码,启用休眠和 Spring 详细日志记录,但仍然......什么都没有。
然后我做了一个(对我来说)令人惊讶的发现。 检查 GWT 响应负载,我看到了这个:
{"S":[false],"O": [{"T":"663_uruC_g7F5h5IXBGvTP3BBKM=","V":"MS4w","S":"IjMi","O":"UPDATE"}],"I":[{"F":true,"M":"Server Error: org.hibernate.PersistentObjectException: detached entity passed to persist: com.myvdm.server.domain.Document; nested exception is javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.myvdm.server.domain.Document"}]}
啊哈,分离的实体传递给坚持! 请注意gwt客户端代码使用这个sn-p调用服务:
requestContext.persist().using(proxy);
可以说这可能会触发异常,调用 merge() 可以解决问题,但是,请继续阅读问题 3...
现在出现三个问题:
- 为什么不以某种方式将其作为错误/异常发送给客户端?
- 为什么 Hibernate 不记录这个?
- 为什么 Spring Roo 生成的代码(如我所说,用作基础)没有表现出这个问题?
非常感谢,
寻求一些意见/建议。
在 T. BROYER 的回应后编辑::
您好 Thomas,感谢您的回复。
我有一个实现 RequestTransport 和 send() 的自定义类。这就是我收集响应负载的方式。实现如下::
public void send(String payload, final TransportReceiver receiver) {
TransportReceiver myReceiver = new TransportReceiver() {
@Override
public void onTransportSuccess(String payload) {
try {
receiver.onTransportSuccess(payload);
} finally {
eventBus.fireEvent(new RequestEvent(RequestEvent.State.RECEIVED));
}
}
@Override
public void onTransportFailure(ServerFailure failure) {
try {
receiver.onTransportFailure(failure);
} finally {
eventBus.fireEvent(new RequestEvent(RequestEvent.State.RECEIVED));
}
}
};
try {
wrapped.send(payload, myReceiver);
} finally {
eventBus.fireEvent(new RequestEvent(RequestEvent.State.SENT));
}
}
这是在编辑模式下单击“保存”按钮时执行的代码:
RequestContext requestContext = editorDriver.flush();
if (editorDriver.hasErrors()) {
return;
}
requestContext.fire(new Receiver<Void>() {
@Override
public void onFailure(ServerFailure error) {
if (editorDriver != null) {
setWaiting(false);
super.onFailure(error);
}
}
@Override
public void onSuccess(Void ignore) {
if (editorDriver != null) {
editorDriver = null;
exit(true);
}
}
@Override
public void onConstraintViolation(Set<ConstraintViolation<?>> errors) {
if (editorDriver != null) {
setWaiting(false);
editorDriver.setConstraintViolations(errors);
}
}
});
根据你说的,应该调用onSuccess(),而且是调用
那么我如何准确地隔离造成问题的代码呢?我有这个方法可以创建一个新的请求上下文以持久化对象
@Override
protected RequestContext createSaveRequestContextFor(DocumentProxy proxy) {
DocumentRequestContext request = requests.documentRequestContext();
request.persist().using(proxy);
return request;
}
这就是它的名称::
editorDriver.edit(getProxy(), createSaveRequestContextFor(getProxy()));
至于 Spring 问题,您是说在两个后续请求 find() 和 persist() 之间,不应关闭 JPA entityManager。我仍在调查此问题,但在按下编辑按钮后,我看到消息“org.springframework.orm.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager”,这是不对的,可能没有应用 @Transactional 注释...
【问题讨论】:
标签: spring hibernate gwt hsqldb requestfactory