我继承了一些代码,在尝试添加一些功能时,这些代码对我不起作用。我不是 Java web 方面的专家,所以如果我需要任何额外的帮助来为您提供所需的信息,我提前道歉。
我正在开发一个 GWT 应用程序,它在后端使用 Hibernate 和 Guice-Persist 来持久保存到 MySQL。不幸的是,我遇到了一个奇怪的问题,其中 - 在一台服务器上 -put
事务没有及时保存到数据库以被后续get
事务识别。在 Windows 和 Linux 的 Tomcat6 中嵌入 GWT Eclipse 插件(可能是 6.1.11?)的任何版本的 Jetty 中,一切都可以完美运行,但是当我尝试使用jetty-maven-plugin
版本在 Linux 中运行它时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 ( per this page ),但没有成功。