You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot调用JPA Repository查询报NullPointerException求助

Spring Boot JPA查询NullPointerException排查与修复

问题场景

实现数据库查询接口时,调用pricingRuleRepository.findByActiveAndValidUptoIsBefore(true, LocalDate.now())抛出NullPointerException,手动执行Hibernate生成的SQL可正常返回结果。

异常信息

java.lang.NullPointerException: null  at
java.base/java.lang.Class.isAssignableFrom(Native Method)

相关代码

Controller

@RequestMapping(path = "/getData", method = RequestMethod.GET)
public List<PricingRuleEntity> getRoRLogEmailzamphia() {
    return reportService.getRoRLogEmail();
}

Service

@Repository
@Transactional
@AllArgsConstructor
public class ReportService {
    private final PricingRuleRepository pricingRuleRepository;
    
    public List<PricingRuleEntity> getRoRLogEmail() {
        List<PricingRuleEntity> list;
        list = pricingRuleRepository.findByActiveAndValidUptoIsBefore(true, LocalDate.now());
        return list;
    }
}

Repository

@Repository
public interface PricingRuleRepository extends JpaRepository<PricingRuleEntity, UUID> {
    List<PricingRuleEntity> findByActiveAndValidUptoIsBefore(boolean active, LocalDate now);
}

Entity类

@Entity
@Data
@Table(name = "pricing_rule")
public class PricingRuleEntity extends BaseEntity {
    @Column(name="applicable_for")
    private String applicableFor;

    @Column(name = "name", unique = true, nullable = false)
    private String name;

    @Column(name="applicable_for_app")
    private String applicableForApp;

    @Column(name = "doc_status", nullable = false)
    private Integer docStatus;

    @Column(name = "creation")
    private String creation;

    @Column(name = "title", nullable = false)
    private String title;

    @Column(name = "disable", nullable = false)
    private Integer disable;

    @Column(name = "apply_on", nullable = false)
    private String applyOn;

    @Column(name = "price_or_product_discount", nullable = false)
    private String priceOrProductDiscount;

    @Column(name = "territory", nullable = false)
    private String territory;

    @Column(name = "min_qty")
    private Double minQty;

    @Column(name = "max_qty")
    private Double maxQty;

    @Column(name = "min_amt")
    private Double minAmt;

    @Column(name = "max_amt")
    private Double maxAmt;

    @Column(name = "valid_from", nullable = false)
    private LocalDate validFrom;

    @Column(name = "valid_upto", nullable = false)
    private LocalDate validUpto;

    @Column(name = "margin_type")
    private String marginType;

    @Column(name = "discount_amount")
    private Double discountAmount;

    @Column(name = "discount_percentage")
    private Double discountPercentage;

    @Column(name = "rule_description")
    private String ruleDescription;

    @Column(name = "promotional_scheme")
    private String promotionalScheme;

    @Column(name = "campaign", nullable = true)
    private String campaign;

    @Column(name = "promotion_image_url")
    private String promotionImageUrl;

    @Type(type = "json")
    @Column(columnDefinition = "JSON")
    public List<PromoItem> items;
}

完整错误日志

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null
    at java.base/java.lang.Class.isAssignableFrom(Native Method)
    at com.vladmihalcea.hibernate.type.json.internal.JsonTypeDescriptor.fromString(JsonTypeDescriptor.java:104)
    at com.vladmihalcea.hibernate.type.json.internal.JsonTypeDescriptor.wrap(JsonTypeDescriptor.java:165)
    at com.vladmihalcea.hibernate.type.json.internal.AbstractJsonSqlTypeDescriptor$1.doExtract(AbstractJsonSqlTypeDescriptor.java:34)
    at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:258)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:254)
    at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:244)
    at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:327)
    at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2775)
    at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1735)
    at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1661)
    at org.hibernate.loader.Loader.getRow(Loader.java:1550)
    at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:734)
    at org.hibernate.loader.Loader.processResultSet(Loader.java:979)
    at org.hibernate.loader.Loader.doQuery(Loader.java:937)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:343)
    at org.hibernate.loader.Loader.doList(Loader.java:2609)
    at org.hibernate.loader.Loader.doList(Loader.java:2592)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2424)
    at org.hibernate.loader.Loader.list(Loader.java:2419)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:502)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:371)
    at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1450)
    at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1402)
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1374)
    at org.hibernate.Query.getResultList(Query.java:417)
    at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:55)
    at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:126)
    at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:88)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:155)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:143)
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137)
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121)
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:159)
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:145)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
    at com.sun.proxy.$Proxy90.findByActiveAndValidUptoIsBefore(Unknown Source)
    at com.blackbird.falcon.service.ReportService.getRoRLogEmail(ReportService.java:25)
    at com.blackbird.falcon.service.ReportService$$FastClassBySpringCGLIB$$e95617ee.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692)
    at com.blackbird.falcon.service.ReportService$$EnhancerBySpringCGLIB$$678591cb.getRoRLogEmail(<generated>)
    at com.blackbird.falcon.controller.DataController.getRoRLogEmailzamphia(DataController.java:24)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:626)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:834)

问题定位

从错误栈可以明确,异常发生在JSON字段items的反序列化阶段,具体是com.vladmihalcea.hibernate.type.json.internal.JsonTypeDescriptor.fromString方法中调用Class.isAssignableFrom时传入了null的Class对象,导致NPE。

核心原因:

  1. 实体类中items字段使用的@Type(type = "json")过于笼统,没有指定具体的JSON类型实现,Hibernate无法正确识别目标泛型类型List<PromoItem>。
  2. 数据库中items字段可能存在NULL值,反序列化时未做处理,导致类型解析失败。
  3. ReportService错误标注@Repository注解,不符合Spring分层规范(非直接原因,但需修正)。

修复方案

1. 修正JSON字段的类型注解

使用com.vladmihalcea提供的具体JSON类型,明确指定泛型类型:

// 替换原有@Type注解
import com.vladmihalcea.hibernate.type.json.JsonType;
import org.hibernate.annotations.Type;

@Type(type = "com.vladmihalcea.hibernate.type.json.JsonType")
@Column(columnDefinition = "JSON")
private List<PromoItem> items;

如果使用Hibernate 5.2+,也可以使用官方原生注解:

import org.hibernate.annotations.JdbcTypeCode;
import
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 23:51:24