Java 在Jetty中未保持时间的事务

Java 在Jetty中未保持时间的事务,java,hibernate,gwt,jpa,guice,Java,Hibernate,Gwt,Jpa,Guice,我继承了一些代码,在尝试添加某些功能时,这些代码对我来说并不正常。我不是Java web方面的专家,因此如果我需要任何额外的帮助来获取您需要的信息,我会提前向您道歉 我正在开发一个GWT应用程序,它在后端使用Hibernate和Guice Persist来持久化到MySQL。不幸的是,我遇到了一个奇怪的问题,在一台服务器上,put事务没有及时持久化到数据库中,以便被后续的get事务识别无论Jetty的哪个版本嵌入了Windows中的GWT Eclipse插件(可能是6.1.11?)和Linux中

我继承了一些代码,在尝试添加某些功能时,这些代码对我来说并不正常。我不是Java web方面的专家,因此如果我需要任何额外的帮助来获取您需要的信息,我会提前向您道歉

我正在开发一个GWT应用程序,它在后端使用Hibernate和Guice Persist来持久化到MySQL。不幸的是,我遇到了一个奇怪的问题,在一台服务器上,
put
事务没有及时持久化到数据库中,以便被后续的
get
事务识别无论Jetty的哪个版本嵌入了Windows中的GWT Eclipse插件(可能是6.1.11?)和Linux中的Tomcat6,但当我尝试在Linux中使用
Jetty maven plugin
version
8.1.0
(也是
8.1.5
,这是我唯一尝试过的两个版本)运行Jetty时,一切都能完美地工作,事务没有及时完成,我就遇到了这个问题。
(或者,如果有一个解决方案可以让我在Maven中使用Jetty以外的其他工具正确地运行集成测试,我会非常激动,以避免这个问题。显然,我试过的所有其他服务器环境中的代码都能正常工作)

下面是我用来持久化对象的代码:

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();
}
并获得这样一个实体管理器:

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()中添加一个过滤器,而不是手动启动持久性会话,以尝试在没有运气的情况下使用每个http请求的会话(per)。

首先,您可能应该在
catch
块中回滚事务,而不是忽略异常(至少记录它)。但是
guice persist
支持
@Transactional
注释,因此实际上您根本不需要进行手动事务管理。请参阅。

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

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;
}

关于,

好吧,你应该从给我们任何信息开始……同意。。。输入标记时过早按enter键。我的错。给我一点时间…只是好奇:调试输出告诉你什么?通常,您应该看到执行了SQLs。您确定它没有抛出一个您只是捕获并静默忽略的异常吗?我没有启用Hibernate的SQL输出。我可以试着确保一切都按正确的顺序进行。另外,我也不敢相信
put()
上有任何错误,因为数据库最终是一致的。因此,一切都正常工作,只是没有按照正确的顺序(在一个环境中)。一个奇怪的条目:
2012-08-23 13:07:04.510:INFO:oejpw.plus配置:找不到事务管理器-如果您的Web应用程序需要事务管理器,请配置一个。
我在其他服务器日志中没有注意到这一点(尽管我可能会丢失它)。谢谢。“do异常处理”中隐藏的实际上是一个
rollback()
调用。我会调查你提到的链接。只是为了确保我理解你的评论。。。您是否建议
@Transactional
注释将更改代码的行为并修复问题?还是更容易维护?UnitOfWork系统的引入是否有助于确保我的数据被及时写入?@Jeff:我不确定它是否能解决你的问题,但如果你让图书馆为你做这些事情,那么用正确的方式做事情总是比较容易的。请注意,
@Transactional
需要在Guice注入的类的方法上。还没有运气,但我认为我们可能朝着正确的方向前进。。。在我的一个
put()
调用中,我得到了一个错误,即
EntityManager已关闭
——看起来我的
提供程序
正在返回EntityManager的已用实例,而不是丢弃它们并创建新实例。是否有其他方法可以创建我的EntityManager?它对以下链接很有用:您能更具体地使用该链接吗?我看不出对这个问题有什么直接的帮助。在发现
EntityManager
s被回收后,我意识到在返回之前对EntityManager进行
clear()
ing可能会解决其中一些问题。事实上,它现在稳定多了,但我必须在每个函数结束时手动
clear()
each
EntityManager
。关于如何处理这个问题有什么想法吗?
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;
}