【发布时间】:2012-08-16 13:26:30
【问题描述】:
我继承了一些代码,当我尝试添加一些功能时,这些代码无法正常工作。我不是 Java 网络方面的专家,所以如果我需要任何额外的帮助来为您提供所需的信息,我提前道歉。
我正在开发一个 GWT 应用程序,它在后端使用 Hibernate 和 Guice-Persist 来持久保存到 MySQL。不幸的是,我遇到了一个奇怪的问题——在一台服务器上——put 事务没有及时保存到数据库中以被后续的get 事务识别。 在 Windows 中嵌入 GWT Eclipse 插件(可能是 6.1.11?)的任何版本的 Jetty 和 Linux 中的 Tomcat6 中,一切都可以完美运行,但是当我尝试在 Linux 中使用 jetty-maven-plugin 版本 8.1.0 运行它时(也在8.1.5 中,我尝试过的唯一两个版本),我遇到了交易未及时完成的问题。(或者,我会很高兴有一个解决方案可以让我正确地使用 Jetty 以外的其他工具在 Maven 中运行我的集成测试,以完全回避这个问题。似乎代码在我尝试过的所有其他服务器上下文中都有效)。
这是我用来持久化对象的代码:
public T put(T entity) {
EntityManager entityManager = entityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
try {
entity = entityManager.merge(entity);
entityManager.persist(entity);
transaction.commit();
} catch (Exception e) {
//do exception handling, including rollback
}
return entity;
}
还有获取代码:
public List<T> getAll() {
Query query = entityManager().createQuery("select c from " + clazz.getSimpleName() + " c");
return (List<T>) query.getResultList();
}
再次,发生的事情是我对getAll() 进行(间接)调用以允许客户端查看数据。然后,如果他们做出选择,请从客户端拨打put 电话。然后,一旦我得到响应,请致电 getAll() 以更新显示给用户的数据。不幸的是,我从数据库返回的数据并没有反映更新的数据,而是在put() 调用之前存在的数据。数据库最终会更新,当我自己检查数据库时,它似乎会立即更新。如果我重新加载数据几次,Web 应用程序最终也会更新以显示正确的数据。所以我怀疑某些缓存层可能会在没有实际检查数据库的情况下响应我的getAll() 请求,但我真的不确定如何继续——事务和实体管理器对我来说相当新。
我已经尝试flush()ing 和close()ing 我的实体管理器而不是提交我的事务,并且行为没有任何变化。
我在构造函数中注入了我的 EntityManager Provider:
private final Class<T> clazz;
private final Provider<EntityManager> entityManagerProvider;
public BaseDao(final Class<T> clazz, final Provider<EntityManager> entityManagerProvider) {
this.clazz = clazz;
this.entityManagerProvider = entityManagerProvider;
}
并获得这样的实体管理器:
protected EntityManager entityManager() {
return entityManagerProvider.get();
}
谢谢!
为了后代,这是我的 GuiceServletContextListener:
public class GuiceServletConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
DispatchServletModule dispatchServletModule = new DispatchServletModule();
Injector injector = Guice.createInjector(new ServerModule(), new JpaPersistModule(getPersistenceUnit()),
dispatchServletModule);
PersistService persistService = injector.getInstance(PersistService.class);
persistService.start();
BootStrapper bootStrapper = injector.getInstance(BootStrapper.class);
bootStrapper.init();
return injector;
}
private String getPersistenceUnit() {
InputStream inputStream = getClass().getResourceAsStream("/database.properties");
if (inputStream == null) {
throw new RuntimeException();
}
try {
Properties properties = new Properties();
properties.load(inputStream);
return properties.getProperty("persistenceUnit");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
还有我的 ServletModule:
public class DispatchServletModule extends ServletModule {
@Override
public void configureServlets() {
serve("/" + ActionImpl.DEFAULT_SERVICE_NAME + "*").with(DispatchServiceImpl.class);
}
}
我尝试在 configureServlets() 中添加一个过滤器,而不是手动启动持久性会话,以尝试使用 session-per-http-request(根据 this page)但没有成功。
【问题讨论】:
-
好吧,你应该先向我们提供任何信息......
-
同意... 输入标签时按回车键太快。我的错。给我一点时间...
-
只是好奇:调试输出告诉你什么?通常您应该看到执行的 SQL。你确定它没有抛出你刚刚捕获并默默忽略的异常吗?
-
我没有启用 Hibernate 的 SQL 输出。我可以尝试一下,以确保一切都以正确的顺序执行。另外,我很犹豫是否认为
put()有任何错误,因为数据库 is 最终是一致的。所以一切正常,只是顺序不正确(在一个环境中)。 -
一个奇怪的条目:
2012-08-23 13:07:04.510:INFO:oejpw.PlusConfiguration:No Transaction manager found - if your webapp requires one, please configure one.我没有在我的其他服务器日志中注意到这一点(尽管我可能会错过它)。
标签: java hibernate gwt jpa guice