我确实有一个问题,我无法弄清楚它会发生什么...... GWT 初学者,从事个人项目。
环境:
具有两个模块的maven项目
一个模块是“模型”,具有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 客户端代码使用此代码段来调用服务:
requestContext.persist().using(代理);
可以说这可能会触发异常,调用 merge() 可以解决问题,但是,请继续阅读问题 3...
现在出现三个问题:
- 为什么不以某种方式将其作为错误/异常发送给客户端?
- 为什么 Hibernate 不记录这个?
- Spring Roo 生成的代码(如我所说,用作基础)如何在没有表现出这个问题的情况下工作?
非常感谢,
等待一些意见/建议。
在 T. BROYER 的回应后编辑::
嗨,托马斯,感谢您的回复。
我有一个实现 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 注释...