JPA Repository.findById() 返回 null 但该值存在于数据库中

问题描述 投票:0回答:5

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

我想知道的是

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.....

控制器

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

       return memberService.isExistByUserId(id);
    }

会员服务

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

存储库

public interface MemberRepository extends CrudRepository<DfMember, String> {
    
}

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

java jpa spring-data-jpa jparepository
5个回答
23
投票

虽然OP已经解决了他的问题,但我必须将我的答案添加到同一问题,但原因不同,因为我确信经过数小时的调试后我在Hibernate的源代码中发现会有帮助(5.4.18 ) 一个 try/catch,当在水合过程中抛出

EntityNotFoundException
时,findBy 返回 null,即使实体存在,并且水合成功。 这是因为相关引用实体不存在并且 Hibernate 期望它存在

例如,我有两个实体 UnitImprovement,其中我存储一个 id 为 5 的单位,以便对 id

0
(不存在)进行改进,然后
unitRepository.findById()
返回 null,而不是 Unit ID 为 5 的实体。

@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;
}

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

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

致以诚挚的问候


4
投票

我想用@Alexpandiyan 的答案添加一些内容。而不是首先通过 ID 查找记录并检查它是否存在。您可以使用预定义函数

existsById
直接在数据库中检查id是否存在,如下所示。

public interface MemberRepository extends CrudRepository<DfMember, String> {
        boolean existsById(String id);
}

更新会员服务功能

memberService.isExistByUser()
.

    public boolean isExistByUserId(String id) {
        return memberRepository.existsById(id);
    }

请参阅文档 https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#new-features.1-11-0


3
投票

您必须将

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

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

       return memberService.isExistByUserId(id);
    }

0
投票

我遇到这种情况是因为一个脚本正在插入数据(同时禁用外键检查),并且父表中不存在引用的 ID 之一,即:

SET FOREIGN_KEY_CHECKS=0;
INSERT INTO company(id, name) VALUES (1, 'Stackoverflow');
INSERT INTO employee(id, first_name, last_name, company_id) VALUES (1, 'John', 'Doe', 1);
INSERT INTO employee(id, first_name, last_name, company_id) VALUES (2, 'Jane', 'Doe', 2);
SET FOREIGN_KEY_CHECKS=1;

Jane Doe
记录引用了
company_id
表中不存在的目标主键值 (
2
=
company
)。

在这种情况下,JPA 的

findById
不会返回任何记录,即使它存在。

修复数据完整性可以解决问题。


0
投票
public boolean isExistByUserId(String id)
{
   Optional<DfMember>member = Optional.ofNullable(memberRepository.findById(id).orElse(new DfMember()));

   return member.isPresent();
}

请更新您的会员服务代码。

© www.soinside.com 2019 - 2024. All rights reserved.