【问题标题】:NullPointerException when initializing Spring data repository初始化 Spring 数据存储库时出现 NullPointerException
【发布时间】:2014-05-03 12:05:38
【问题描述】:

我有带有 Spring、Hibernate/JPA 和 Spring Data 的 webapp。我为某些实体创建了扩展 JpaRepository 的存储库,并且使用 .save(T) 或 saveAndFlush、findAll 等默认方法一切都很好,即使使用 findBy,如果某些字段名称很简单,例如 id (findById) 或 findByRole - 其中 Role 是枚举或 findByActive 其中 active 是给定实体中的布尔字段。 但是当我尝试对复杂对象的字段做同样的事情时,我遇到了麻烦。我有一个名为 Person 的实体。人有字段

私人用户管理器;

使用 getter/setter。当我尝试将其放在 PersonRepository 中时:

public interface PersonRepository extends JpaRepository<Person, Long> {

    List<Person> findByManager(User manager);
}

我在应用部署期间遇到了异常:

Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'PersonRepository': Invocation of init method failed; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1512)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:610)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:632)
    at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1740)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:618)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:565)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1487)
    at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:97)
    at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1328)
    at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1420)
    at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:848)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322)
    at sun.rmi.transport.Transport$1.run(Transport.java:177)
    at sun.rmi.transport.Transport$1.run(Transport.java:174)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:556)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:811)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:670)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.NullPointerException
    at org.springframework.data.jpa.repository.query.QueryUtils.getOrCreateJoin(QueryUtils.java:522)
    at org.springframework.data.jpa.repository.query.QueryUtils.toExpressionRecursively(QueryUtils.java:459)
    at org.springframework.data.jpa.repository.query.JpaQueryCreator$PredicateBuilder.build(JpaQueryCreator.java:199)
    at org.springframework.data.jpa.repository.query.JpaQueryCreator.toPredicate(JpaQueryCreator.java:146)
    at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:86)
    at org.springframework.data.jpa.repository.query.JpaQueryCreator.create(JpaQueryCreator.java:44)
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createCriteria(AbstractQueryCreator.java:109)
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:88)
    at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:73)
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.<init>(PartTreeJpaQuery.java:98)
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$CountQueryPreparer.<init>(PartTreeJpaQuery.java:186)
    at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:60)
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:91)
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:162)
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:69)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:304)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:161)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:224)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:210)
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:84)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1571)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1509)
    ... 55 more

我什至尝试过类似的东西:findByManagerId(Lond id); 和其他一些组合,都一样。有任何想法吗?

我的 pom.xml 中的 importanp 部分:

 <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>3.5.1-Final</version>
        </dependency>
   <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.0-api</artifactId>
            <version>1.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>1.5.1.RELEASE</version>
        </dependency>

【问题讨论】:

  • 粘贴您对PersonUser 的定义。
  • 您使用的是哪个 Hibernate 版本?似乎异常是由 Hibernate 从对 getJoins() 的调用返回 null 引起的,这显然不应该。此外,您的 manager 属性必须用 @ManyToOne 注释,以防它已经不是(您上面的示例没有显示它)。
  • 已经是@ManyToOne。这是我的 hibernate 和 spring 数据 pom:我会在一分钟内在问题中添加依赖项!

标签: java spring hibernate jpa spring-data


【解决方案1】:

这解决了我的问题(在应用程序初始化期间仍然不知道 NullPointerException 是什么),但无论如何,这有帮助(在我的 PersonRepository 中):

@Query("SELECT person from Person person where person.manager=:manager")
public List<Person> findByManager(@Param("manager")User manager);

并挽救了我的一天......我仍然认为这应该可以在没有查询的情况下工作,并且 NPE 看起来像一个错误。谢谢大家!

【讨论】:

    【解决方案2】:

    这并不能直接回答您为什么得到空指针,但您可以尝试为该查询创建自定义实现。阅读 this documentation 的 1.3 以获取有关如何执行此操作的信息。

    【讨论】:

    • 我已经做到了。 doc 中的 findByEmail 和我的 findByManager 有什么区别?对象的复杂性?
    • 来自文档:但是,您也可以通过遍历嵌套属性来定义约束。假设人员有带有邮政编码的地址。在这种情况下,方法名称为 List findByAddressZipCode(ZipCode zipCode);创建属性遍历 x.address.zipCode。
    • 并且:解析算法首先将整个部分 (AddressZipCode) 解释为属性,并检查域类中具有该名称的属性(未大写)。如果算法成功,它将使用该属性。如果不是,该算法将源在驼峰部分从右侧拆分为头部和尾部,并尝试找到相应的属性,在我们的示例中为 AddressZip 和 Code。如果算法找到具有该头部的属性,它将获取尾部并继续从那里向下构建树,以刚才描述的方式将尾部拆分。
    • 并且:如果第一次拆分不匹配,算法将拆分点向左移动(地址,邮编)并继续。
    • 嗯,这很酷。在那种情况下,我不知道你为什么得到空指针,但我仍然觉得使用 Spring Data,当你遇到逆风试图以自动方式进行时,使用一些自定义查询自定义存储库通常更容易。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-30
    • 1970-01-01
    • 2013-09-12
    • 2017-04-06
    相关资源
    最近更新 更多