4

我继承了一些代码,在尝试添加一些功能时,这些代码对我不起作用。我不是 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 ),但没有成功。

4

2 回答 2

0

首先,您可能应该回滚catch块中的事务并且不要忽略异常(至少记录它)。但是guice-persist支持@Transactional注解,所以你根本不需要手动进行事务管理。请参阅事务 - google-guice

于 2012-08-16T13:43:21.250 回答
0

您是否希望关闭与事务关联的会话?

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
    } finally {
        entityManager.close();
    }

    return entity;
}

但是您可以强制事务与刷新同步:

public T put(T entity) {
    EntityManager entityManager = entityManager();
    EntityTransaction transaction = entityManager.getTransaction();        
    transaction.begin();
    try {
        entity = entityManager.merge(entity);
        entityManager.persist(entity);
        entityManager.flush();
        transaction.commit();

    } catch (Exception e) {
        //do exception handling, including rollback
    }

    return entity;
}

问候,

于 2012-08-24T09:40:04.550 回答