简体   繁体   English

测试 JpaRepository findById 为 UUID 返回 null

[英]Test JpaRepository findById returns null for UUID

Spring newbie here, Spring 新手在这里,
I want to test the the findById() method of a repository, but it cannot find the entry even through it is saved (and exists) in the database:我想测试存储库的findById()方法,但即使它已保存(并存在)在数据库中,它也无法找到该条目:

@DataJpaTest
class CustomerRepoIntegration {

    @Autowired
    CustomerRepo customerRepo;

    @Test
    @Transactional
    void findById() {
        UUID uuid = UUID.randomUUID();
        Customer customer = new Customer(uuid);
        customerRepo.save(customer);

        List<Customer> allCustomers = customerRepo.findAll();
        assertEquals(1, allCustomers.size());

        Optional<Customer> foundCustomer = customerRepo.findById(uuid);
        assertTrue(foundCustomer.isPresent());
    }
}

While the first assert is successful the second fails with:虽然第一个断言成功,但第二个断言失败:

Error:  Failures: 
Error:    CustomerRepoIntegration.findById:32 expected: <true> but was: <false>

The rest of the code: rest的代码:

// CustomerRepo.java
public interface CustomerRepo extends JpaRepository<Customer, UUID> {}
// Customer.java
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Customer implements Serializable {
    @Id
    @GeneratedValue(generator = "UUID")
    @GenericGenerator(
            name = "UUID",
            strategy = "org.hibernate.id.UUIDGenerator"
    )
    private UUID id;
}

I also made a reproduction repo here: https://github.com/ofhouse/stackoverflow-65818312我还在这里做了一个复制回购: https://github.com/ofhouse/stackoverflow-65818312

Try to use尝试使用

customerRepo.saveAndFlush(customer) instead save(customer) customerRepo.saveAndFlush(customer)而不是save(customer)

Moreover, if you have configured an entity annotation responsible for auto-generating the id, the better idea would be not interfering in this mechanism creating your own UUID and initialize the entity.此外,如果您配置了负责自动生成 id 的实体注释,则更好的方法是不要干扰创建您自己的 UUID 并初始化实体的机制。 Hibernate will do it automatically for you. Hibernate 会自动为您完成。

Why not?为什么不?

Hibernate has its own mechanism depends on the marked field with @Id annotation whether to merge or persist entity with EntityManager (If the field is null or contains data). Hibernate 有自己的机制取决于带有@Id注释的标记字段是否与EntityManager 合并或持久化实体(如果该字段为null 或包含数据)。

Instead of代替

UUID uuid = UUID.randomUUID();
Customer customer = new Customer(uuid);

You can simply do你可以简单地做

Customer customer = new Customer();

And fetch UUID from a persisted instance of entity here:并在此处从实体的持久实例中获取 UUID:

var persistedCustomer = customerRepo.saveAndFlush(customer);
...
Optional<Customer> foundCustomer = customerRepo.findById(persistedCustomer.uuid);

For people using spring-boot 2.7.X, which ships with hibernate-core:5.6.10 the actual problem is explained here .对于使用 spring-boot 2.7.X 的人,它附带 hibernate-core:5.6.10,实际问题在此处解释。

By adding columnDefinition = "uuid" to the UUID @Column() definition the problem was solved on h2.通过将 columnDefinition = "uuid" 添加到 UUID @Column() 定义中,问题在 h2 上得到解决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM