查询未返回唯一结果:4;嵌套异常是 javax.persistence.NonUniqueResultException:查询没有返回唯一结果:4

Posted

技术标签:

【中文标题】查询未返回唯一结果:4;嵌套异常是 javax.persistence.NonUniqueResultException:查询没有返回唯一结果:4【英文标题】:query did not return a unique result: 4; nested exception is javax.persistence.NonUniqueResultException: query did not return a unique result: 4 【发布时间】:2020-10-15 17:18:52 【问题描述】:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureMockMvc
class LoginTest 

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private UserService userService;

    @MockBean
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Test
    void contextLoads() throws Exception 
        mockMvc.perform(get("/login"))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(content().string(containsString("Welcome to Klaud")))
                .andExpect(content().string(containsString("Sign in")));
    

    @Test
    void shouldSuccessfullyLogin() throws Exception 
        Role userRole = mock(Role.class);
        userRole.setRole("USER");

        User user = mock(User.class);
        user.setId(99);
        user.setFirstName("Donald");
        user.setLastName("Duck");
        user.setEmail("duck@gmail.com");
        user.setPassword(bCryptPasswordEncoder.encode("12345678"));
        user.setActive(1);
        user.setRoles(new HashSet<>(Collections.singletonList(userRole)));
        userService.saveUser(user);

        mockMvc.perform(post("/login")
            .param("email", "test@gmail.com")
            .param("password", "test")
        ).andExpect(redirectedUrl("/home"));
    

我正在努力为用户登录编写集成测试,并在我想保存模拟用户时收到此错误。如何创建用户并保存到数据库?

源码:https://github.com/camerons2001/Klaud

Fullstracktrace 错误:

org.springframework.dao.IncorrectResultSizeDataAccessException: query did not return a unique result: 4; nested exception is javax.persistence.NonUniqueResultException: query did not return a unique result: 4

    at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:385)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:257)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:528)
    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:149)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.sun.proxy.$Proxy114.findByRole(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

还有更多...

我正在使用 Spring Boot。

【问题讨论】:

为什么在编写实际集成测试时还要模拟用户?模拟用户不包含任何内容(调用 setter 什么都不做),因此您存储的是一个空用户。另外请添加完整的堆栈跟踪以查看错误的来源。 我正在尝试创建一个新用户并想检查该用户是否已创建。用户不应该被嘲笑吗? 不,因为调用 setter 什么都不做,所以没有数据。导致错误的查询是findByRole。您的数据库中有更多具有特定角色的用户,这是预期的。 我试图删除 findByRole,但我得到了同样的错误。 我怀疑这是完全相同的错误。除非你没有删除它。我也不认为这是你日志中的完整记录(其中缺少太多)。 【参考方案1】:

模拟用户时最好不要设置 userId。这是不好的做法,会带来副作用。并且您应该在测试后回滚所有数据库更改。在 LoginTest 类的顶部使用 @Transactional 在测试执行后回滚它。

【讨论】:

github.com/camerons2001/Klaud/blob/master/src/main/java/com/… 在模拟用户时最好不要设置 userId。这是不好的做法,会带来副作用。并且您应该在测试后回滚所有数据库更改。在 LoginTest 类的顶部使用 @Transactional 当然,我删除了 setId。这就是我正在考虑的,我需要在成功的测试通过后创建用于模拟和从数据库中删除的用户。 @camerons2001 清理数据库,添加注释,删除 userId 集并重试 该问题与设置用户 ID 无关(也不会产生任何影响,因为用户是一个模拟用户。设置 someting 什么都不做。调用 getUserid 将返回 null 或者如果是 primitve默认值。它是模拟的,不是真实的用户实例。【参考方案2】:

对于数据库表中的同一行。请从表格中删除重复的数据行。

【讨论】:

正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于查询未返回唯一结果:4;嵌套异常是 javax.persistence.NonUniqueResultException:查询没有返回唯一结果:4的主要内容,如果未能解决你的问题,请参考以下文章

org.hibernate.NonUniqueResultException:查询未返回唯一结果:462

与where子句查询的Eloquent嵌套关系在false条件下返回集合

汇总开发过程中遇到的坑

解析云代码嵌套查询时未调用代码 141 成功/错误消息

使用 Prisma 的嵌套创建查询返回未定义

如果嵌套查询在 SQL Server 中是不是有结果,如何返回是或否?