我在桌面应用程序中使用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!
}
My 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<PersistenceManager>.
*/
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没有得到正确约束?有什么想法吗?
答案 0 :(得分:1)
您的main.run()
- 方法有何功能?它会调用PersistenceManagerFilter#doFilter
吗?如果没有,则ThreadLocal<PersistenceManager>
中的值将为空...
您可以覆盖initialValue()
并执行以下操作:
ThreadLocal<PersistenceManager> pm = new ThreadLocal<PersistenceManager>(){
@Override
protected PersistenceManager initialValue() {
return JDOHelper.getPersistenceManagerFactory().getPersistenceManager();
}
};
您还应该记得在finally块中调用ThreadLocal#remove()
方法。
您可以直接在guice-module中绑定ThreadLocal
,而不是自己处理PersistenceManager
:
class GuiceModule extends AbstractModule {
@Provides @RequestScoped
PersistenceManager providePersistenceManager(){
return JDOHelper.getPersistenceManagerFactory().getPersistenceManager();
}
@Override
protected void configure() {}
}