JPA Repository.findById() 返回 null 但该值存在于 db

Jin*_*ark 9 java jpa spring-data-jpa

我正在使用 JPA 开发 Spring boot 项目。

我想知道的是 repository.findById(id) 方法返回 null,而数据在数据库中可用。

功能save()findAll()工作正常。当我在 junit 测试环境中运行相同的代码时,它完全有效。如果数据是硬编码的,比如memberRepository.findById("M001");,它工作正常。

实体

@Entity
@Table(name="df_member")
public class DfMember {
    
    @Column(name="member_type")
    private String memberType;

    @Id
    @Column(name="id")
    private String id;
    
        ...columns...
        ...Getters/Setters.....
Run Code Online (Sandbox Code Playgroud)

控制器

    @ResponseBody
    @RequestMapping(value="/checkIdDuplicate", method=RequestMethod.POST)
    public boolean checkIdDuplicate(@RequestBody String id) {

       return memberService.isExistByUserId(id);
    }
Run Code Online (Sandbox Code Playgroud)

会员服务

    public boolean isExistByUserId(String id) {
        Optional<DfMember> member = memberRepository.findById(id);
        return member.isPresent();
    }
Run Code Online (Sandbox Code Playgroud)

存储库

public interface MemberRepository extends CrudRepository<DfMember, String> {
    
}
Run Code Online (Sandbox Code Playgroud)

应该返回成员对象,但它为空。

Kev*_*ias 10

While the OP has solved his issue, I have to add my answer to the same problem, but with a different cause, because I'm sure will be helpful after hours of debugging I found in the source code of Hibernate (5.4.18) a try/catch that when a EntityNotFoundException is thrown in the hydration process the findBy returns null, even if the entity exists, and it's hydrated successfully. This is because a related referenced entity doesn't exists and Hibernate expect it to exists

例如,我有两个实体UnitImprovement,其中我存储了一个 id 为 5 的单元,以便对 id 进行改进0(不存在),然后unitRepository.findById()返回 null,而不是 id 为 5 的 Unit 实体。

@Entity
@Table(name = "units")
public class Unit {
    @ManyToOne(fetch = FetchType.LAZY)
    @Fetch(FetchMode.JOIN)
    @JoinColumn(name = "improvement_id")
    @Cascade({ CascadeType.MERGE, CascadeType.PERSIST, CascadeType.DELETE })
    private Improvement improvement;
}
Run Code Online (Sandbox Code Playgroud)

发生这种情况的原因是因为进口脚本中使用0作为值improvement_id而不是原始NULL。

提示:在导入脚本中禁用外键检查时要小心

此致

  • 我不知道该怎么感谢你,是你救了我!非常感谢这个有价值的答案。数据库上的 EAGER 字段不应为空。 (3认同)
  • 同样的问题。在我的例子中,我错误地将引用列的默认值设置为 0 而不是 NULL,这导致连接失败,因此 findById 返回 null/可选为空。 (2认同)

Ale*_*kan 3

你必须更改@RequestBody@RequestParam. 请按如下所示更新您的控制器代码。

    @ResponseBody
    @RequestMapping(value="/checkIdDuplicate", method=RequestMethod.POST)
    public boolean checkIdDuplicate(@RequestParam String id) {

       return memberService.isExistByUserId(id);
    }
Run Code Online (Sandbox Code Playgroud)