Упорство Guice с JDO - странный NPE - PullRequest
0 голосов
/ 18 января 2012

Я использую Guice с JDO и Datanucleus в своем настольном приложении.Я сталкиваюсь с NPE, который я не могу исправить, поэтому я надеюсь, что кто-то может помочь мне:)

Я использую правильно сконфигурированную H2 db, со схемой, и все мои классы приятно улучшены, так что это не так,В любом случае, я получаю NPE здесь, в классе JDORepository:

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

Я начинаю все это так:

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

Так что привязки репозитория в основном классе работают нормально, так как они перенаправляются в JDORepository.Это что-то на более низком уровне, PMF не связывается должным образом?Есть идеи?

1 Ответ

1 голос
/ 18 января 2012

Что делает ваш main.run() -метод?Это звонит PersistenceManagerFilter#doFilter?Если этого не произойдет, значение в вашем ThreadLocal<PersistenceManager> будет нулевым ...

Вы можете переопределить initialValue() и сделать что-то вроде этого:

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

Вам также следуетне забудьте вызвать метод ThreadLocal#remove() в вашем блоке finally.

Вместо того, чтобы обрабатывать ThreadLocal самостоятельно, вы можете связать PersistenceManager непосредственно в модуле guice:

class GuiceModule extends AbstractModule {

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

    @Override
    protected void configure() {}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...