query did not return a unique result: 2;

微信小程序开发者工具控制台报错

在这里插入图片描述

{
  "timestamp": "2024-12-05T05:41:32.005+0000",
  "status": 500,
  "error": "Internal Server Error",
  "message": "query did not return a unique result: 2; nested exception is javax.persistence.NonUniqueResultException: query did not return a unique result: 2",
  "path": "/admin/signIn"
}

检查服务器报错信息

18616239629
2024-12-05 13:41:32.000  INFO 1287 --- [-nio-443-exec-5] c.p.a.c.MyAuthenticationSuccessHandler   : 管理员:18616239629 登录成功 登录IP:139.227.122.92
2024-12-05 13:41:32.004 ERROR 1287 --- [-nio-443-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception

org.springframework.dao.IncorrectResultSizeDataAccessException: query did not return a unique result: 2; nested exception is javax.persistence.NonUniqueResultException: query did not return a unique result: 2
        at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:378)
        at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:255)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:527)
        at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
        at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
        at com.sun.proxy.$Proxy173.findByAdminIdAndCreatedDateAfter(Unknown Source)
        at com.productQualification.user.service.LoginLogService.findByAdminIdToday(LoginLogService.java:24)
        at com.productQualification.api.service.LoginLogApiService.save(LoginLogApiService.java:17)
        at com.productQualification.api.config.MyAuthenticationSuccessHandler.onAuthenticationSuccess(MyAuthenticationSuccessHandler.java:95)
        at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.successfulAuthentication(AbstractAuthenticationProcessingFilter.java:326)
        at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:240)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:668)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:791)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)
Caused by: javax.persistence.NonUniqueResultException: query did not return a unique result: 2
        at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:128)
        at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
        at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1561)
        at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getSingleResult(CriteriaQueryTypeQueryAdapter.java:109)
        at sun.reflect.GeneratedMethodAccessor322.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:402)
        at com.sun.proxy.$Proxy354.getSingleResult(Unknown Source)
        at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:214)
        at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:91)
        at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:136)
        at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:125)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:605)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
        ... 67 common frames omitted

javax.persistence.NonUniqueResultException 这个错误,是因为我们发送登录请求时 https://api.crossbiog.com/admin/signIn,返回的登录日志结果有两个,所以报错。
从报错中找到查询方法findByAdminIdAndCreatedDateAfter这个很关键

错误原因分析

报错信息提示了一个关键异常:

javax.persistence.NonUniqueResultException: query did not return a unique result: 2

这表明在执行查询时,JPA 期望返回一个唯一结果(即单条记录),但实际返回了 2 条记录。根本原因通常在于查询返回了多于一条数据,而方法只允许返回一个结果。

关键位置

错误栈中相关位置:

at com.productQualification.user.service.LoginLogService.findByAdminIdToday(LoginLogService.java:24)
at com.productQualification.api.service.LoginLogApiService.save(LoginLogApiService.java:17)
at com.productQualification.api.config.MyAuthenticationSuccessHandler.onAuthenticationSuccess(MyAuthenticationSuccessHandler.java:95)

查询方法:

findByAdminIdAndCreatedDateAfter

可能原因

  1. 数据库中有多条符合条件的记录:查询条件返回了多条记录,但方法如 getSingleResult()Optional<T>.orElseThrow() 只期望返回一条。
  2. 逻辑错误:业务逻辑可能预期不会出现多条结果,但数据问题导致返回了多条。
  3. 查询方式
    • 使用了 getSingleResult(),但实际结果集不唯一。
    • 可能是通过 findFirst()Optional 处理,查询仍返回多条。

解决方法

1. 检查数据库数据
  • 确认 findByAdminIdAndCreatedDateAfter 所查询的表中是否有重复数据。
  • 使用查询条件 adminIdcreatedDate,手动查询数据库,检查返回的记录是否超过 1 条。

示例 SQL:

SELECT * FROM login_logs WHERE admin_id = '18616239629' AND created_date > '2024-12-05';
2. 修改查询方法

如果业务逻辑允许多条结果,使用 getResultList() 替代 getSingleResult()

List<LoginLog> logs = query.getResultList();
if (!logs.isEmpty()) {
    return logs.get(0); // 或者按业务需求处理
}
3. 限定查询返回唯一结果

确保查询只返回一条数据,可以加上 LIMIT 1 或调整查询条件:

@Query("SELECT l FROM LoginLog l WHERE l.adminId = :adminId AND l.createdDate > :createdDate ORDER BY l.createdDate DESC")
Optional<LoginLog> findFirstByAdminIdAndCreatedDateAfter(@Param("adminId") String adminId, @Param("createdDate") Date createdDate);
4. 检查业务逻辑

LoginLogService 中,确认 findByAdminIdToday 是否处理了返回多条数据的情况。

总结

该错误通常是因为数据不唯一导致的,解决方法是要么确保数据库中的数据唯一,要么修改查询方法使其能处理多条记录。

1、LoginLogRepository

ptional<LoginLog> findByAdminIdAndCreatedDateAfter(Integer adminId, Date date);

2、LoginLogService

    public Optional<LoginLog> findByAdminIdToday(Integer adminId) {
        Date today = DateUtil.getLocalDate();
        return loginLogRepository.findByAdminIdAndCreatedDateAfter(adminId, today);
    }

3、LoginLogApiService

    public LoginLog save(Integer adminId, String ip) {
        Optional<LoginLog> loginLogOptional = loginLogService.findByAdminIdToday(adminId);
        return loginLogOptional.orElseGet(() -> loginLogService.save(new LoginLog(adminId, ip)));
    }

4、MyAuthenticationSuccessHandler

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication auth) throws IOException, ServletException {
        String username = auth.getName();
        System.out.println(username);
        Admin admin = adminCacheService.findByUsername(username);

        //校验域名是否正确
        List<Role> roles = roleCacheService.findRolesByAdminId(admin.getId());
        String roleName = null;
        String introduction = null;
        if (!roles.isEmpty()) {
            Role role = roles.get(0);
            roleName = role.getName();
//            introduction = role.getIntroduction();
        }

        request.getSession().setAttribute(Constants.ADMIN_ID, admin.getId());
        request.getSession().setAttribute(Constants.ADMIN_NAME, admin.getUsername());

        admin.setPasswordAttemptCount(0);
        admin.setLockedDate(null);
        admin.setLastLoginTime(new Date());
        admin.setStatus(Admin.NORMAL_STATUS);
        adminCacheService.save(admin);
        String ip = IPUtil.getClientIP(request);
        logger.info("管理员:{} 登录成功 登录IP:{}", username, ip);

        AdminAdminDTO adminAdminDTO = JSON.parseObject(JSON.toJSONString(admin), AdminAdminDTO.class);
        adminAdminDTO.setRole(roleName);
//        if (null != appConfig) {
//            adminAdminDTO.setLogo(appConfig.getLogo());
//            adminAdminDTO.setLogoMin(appConfig.getLogoMin());
//        }
//        return BaseResult.success(adminAdminDTO);

//        User user = (User)auth.getPrincipal();
        String token = JwtUtils.createToken(admin.getId().toString(), "admin", username, roleName);
        adminAdminDTO.setToken(token);
//        adminAdminDTO.setIntroduction(introduction);
        loginLogApiService.save(admin.getId(), ip);
        adminAdminDTO.setVip(adminService.isSuper(admin.getId()) || subscribeService.isVIP(admin.getId()));
        adminAdminDTO.setCopywritingEditor(copywritingEditorService.findByEditorIdAndType(admin.getId(), 1).isPresent());
        adminAdminDTO.setCommunityLinkEditor(adminService.isCommunity(admin.getId()) || copywritingEditorService.findByEditorIdAndType(admin.getId(), 2).isPresent());
        adminAdminDTO.setMaterialInspirationer(copywritingEditorService.findByEditorIdAndType(admin.getId(), 3).isPresent());
        adminAdminDTO.setIndustryStandardEditor(copywritingEditorService.findByEditorIdAndType(admin.getId(), 4).isPresent());
        adminAdminDTO.setCustomerEditor(copywritingEditorService.findByEditorIdAndType(admin.getId(), 5).isPresent());
        adminAdminDTO.setLogisticsCalculationEditor(copywritingEditorService.findByEditorIdAndType(admin.getId(), 6).isPresent());
        adminAdminDTO.setPromotionRegistrationEditor(copywritingEditorService.findByEditorIdAndType(admin.getId(), 7).isPresent());
        adminAdminDTO.setSynergyEditor(copywritingEditorService.findByEditorIdAndType(admin.getId(), 8).isPresent());
        adminAdminDTO.setExamEditor(copywritingEditorService.findByEditorIdAndType(admin.getId(), 9).isPresent());
        adminAdminDTO.setPageAuditEditor(copywritingEditorService.findByEditorIdAndType(admin.getId(), 10).isPresent());
        adminAdminDTO.setFakeRegistrationEditor(copywritingEditorService.findByEditorIdAndType(admin.getId(), 11).isPresent());
        adminAdminDTO.setFakeComparor(fakeConfigService.findByCompareAdminId(admin.getId()).isPresent());
        ResponseUtil.out(response, BaseResult.success(adminAdminDTO));
    }

我们登录阿里云数据库,查看登录日志

SELECT * FROM `login_log` 
 WHERE `admin_id` = 75

在这里插入图片描述
发现数据库中确实有两条一模一样的登录记录,都在同一时刻,只有ip地址不同,所以返回了两条记录,所以报了上述错误,我们只需要删除一条即可。

SELECT * FROM login_log WHERE admin_id = '75' AND created_date > '2024-12-05'

在这里插入图片描述

DELETE FROM login_log WHERE id = 1808;

在这里插入图片描述
在这里插入图片描述
此时不在报上述错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值