2012-01-17 11 views
-1

私はデスクトップアプリケーションでJDOとDatanucleusでGuiceを使用しています。私は修正できないNPEに直面しているので、誰かが私を助けてくれることを願っています:)JDOでGuiceの永続性 - 奇妙なNPE

スキーマが作成されたH2 dbを適切に使用していて、すべてのクラスがうまく強化されています。とにかく、私はJDORepositoryクラスで、ここでNPEを取得しています:

public abstract class JdoRepository<T> implements Repository<T> 
{ 
private final Class<T> clazz; 
private final Provider<PersistenceManager> pmProvider; 

protected JdoRepository(Class<T> clazz, Provider<PersistenceManager> pmProvider) 
{ 
    this.clazz = clazz; 
    this.pmProvider = pmProvider; 
} 
public void persist(T entity) 
{ 
    pmProvider.get().makePersistent(entity); <---- NPE! 
} 

私PersistenceManagerFilterは以下のようになります。

@Singleton 
    public class PersistenceManagerFilter implements Filter 
    { 
    private static final Logger logger = Logger.getLogger(PersistenceManagerFilter.class.getName()); 

    private static final ThreadLocal<PersistenceManager> pm = new ThreadLocal<PersistenceManager>(); 

    private PersistenceManagerFactory pmf; 

    public void init(FilterConfig filterConfig) throws ServletException 
    { 
     logger.info("Creating PersistenceManagerFactory"); 
     pmf = JDOHelper.getPersistenceManagerFactory(); 
    } 

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
      throws IOException, ServletException 
    { 
     try 
     { 
      pm.set(pmf.getPersistenceManager()); 
      chain.doFilter(request, response); 
     } 
     finally 
     { 
      pm.get().close(); 
     } 
    } 

    public void destroy() 
    { 
     logger.info("Closing PersistenceManagerFactory"); 
     pmf.close(); 
    } 

    /** 
    * This module binds the JDO {@link javax.jdo.PersistenceManager} interface to the provider that allows the 
    * implementation to be injected as Provider&lt;PersistenceManager&gt;. 
    */ 
    public static class GuiceModule extends AbstractModule 
    { 
     @Override 
     protected void configure() 
     { 
      bind(PersistenceManager.class).toProvider(new Provider<PersistenceManager>() 
      { 
       public PersistenceManager get() 
       { 
        return PersistenceManagerFilter.pm.get(); 
       } 
      }); 
     } 
    } 
} 

責任モジュール:

public class GuiceModule extends AbstractModule 
    { 
    @Override 
    protected void configure() 
    { 
     // Enable per-request-thread PersistenceManager injection. 
     install(new PersistenceManagerFilter.GuiceModule()); 
     bind(new TypeLiteral<Repository<Project>>() { }).to(JdoProjectRepository.class); 

私はそれにそのすべてを開始していますway:

Injector injector = Guice.createInjector(new GuiceModule()); 
    Main main = injector.getInstance(Main.class); 
    main.run(); 

したがって、JDORepositoryにリダイレクトされるので、メインクラスのリポジトリバインディングはうまく動作します。それは低レベルで何か、PMFは適切に束縛されていませんか?何か案は?

答えて

1

main.run()の方法は何ですか?それはPersistenceManagerFilter#doFilterに電話しますか?そうでない場合は、あなたのThreadLocal<PersistenceManager>の値はnullになります...

あなたはinitialValue()をオーバーライドして、このような何か行うことができます:あなたは、あなたの中にThreadLocal#remove()メソッドを呼び出すために覚えておく必要があります

ThreadLocal<PersistenceManager> pm = new ThreadLocal<PersistenceManager>(){ 
    @Override 
    protected PersistenceManager initialValue() { 
     return JDOHelper.getPersistenceManagerFactory().getPersistenceManager(); 
    } 
}; 

を最終ブロック。

代わりThreadLocal自分自身を扱うのは、Guiceのモジュールに直接PersistenceManagerをバインドすることができます:

class GuiceModule extends AbstractModule { 

    @Provides @RequestScoped 
    PersistenceManager providePersistenceManager(){ 
     return JDOHelper.getPersistenceManagerFactory().getPersistenceManager(); 
    } 

    @Override 
    protected void configure() {} 
} 
+0

いや、私は私のrun()メソッドにそれのようなものを追加しませんでした。私が持っているのは – Paul

+0

なので、私はrun()メソッドに何も追加しませんでした。私が持っているものはすべて @Inject \t公開リポジトリ projectRepo; ... projectRepo.persist(newProject); どこに追加するかわからない:)あなたのコードを追加するには、いくつかの置き換えが必要だと思います。 RequestScopedは基本アノテーションではありません。 ええと... main.run()に何を追加しますか? – Paul

+0

申し訳ありません、私はあなたが 'guice-servlet'拡張を使用していると仮定しました。 @RequestScoped注釈は、その拡張機能によって提供されます。 あなたのコードでは、 'doFilter'の' ThreadLocal'の値を設定します。 'main#run()'から 'doFilter'を呼び出すか、' ThreadLocal'の 'initialValue()'をオーバーライドしてください。 – eiden