4

一部の機能を追加しようとすると、正しく機能しないコードを継承しました。私は Java Web の専門家ではないので、必要な情報を得るために余分な手がかりが必要な場合は、事前にお詫び申し上げます。

バックエンドでHibernateとGuice-Persistを使用してMySQLに永続化するGWTアプリケーションを開発しています。put残念ながら、あるサーバーで、後続のトランザクションによって認識されるまでにトランザクションがデータベースに保持されないという奇妙な問題に直面していますgetWindowsのGWT Eclipseプラグイン(おそらく6.1.11?)とLinuxのTomcat6に組み込まれているJettyのバージョンに関係なく、すべてが完全に機能しますが、jetty-maven-pluginバージョンを使用してLinuxで実行しようとすると8.1.08.1.52つだけのバージョンでも)試してみました)、トランザクションが時間内に完了しないという問題が発生します。(別の方法として、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()データベースを実際にチェックせずにリクエストしますが、続行する方法が本当にわかりません.TransactionsとEntityManagersは私にとってかなり新しいものです.

flush()トランザクションをコミットする代わりに、Entity Manager をing およびingしようとしましclose()たが、動作に変化はありませんでした。

コンストラクターに EntityManager プロバイダーを挿入しています。

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


}

そして私のサーブレットモジュール:

public class DispatchServletModule extends ServletModule {      
  @Override
  public void configureServlets() {
    serve("/" + ActionImpl.DEFAULT_SERVICE_NAME + "*").with(DispatchServiceImpl.class);
  }
}

session-per-http-request (このページごと) を使用しようとして、永続化セッションを手動で開始する代わりに、 configureServlets() にフィルターを追加しようとしましたが、うまくいきませんでした。

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 に答える