【问题标题】:JPA Repository.findById() returns null but the value is exist on dbJPA Repository.findById() 返回 null 但该值存在于 db
【发布时间】:2019-07-16 03:02:01
【问题描述】:

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

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

函数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> {
    
}

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

【问题讨论】:

  • 也许我遗漏了一些东西,但我到处看到“它有效”、“它也有效”等。它什么时候有效?
  • 打印id 并检查其中是否有空格
  • 打印 ID 不是空格。它具有价值
  • @kartik 也不例外。 “它有效”意味着返回成功(不是 null )。
  • @Jin-gukPark 嘿,你能解决这个问题吗?我也面临同样的问题

标签: java jpa spring-data-jpa


【解决方案1】:

虽然 OP 解决了他的问题,但我必须将我的答案添加到同一个问题,但原因不同,因为我确信经过数小时的调试后我在 Hibernate 的源代码中找到的(5.4 .18) 一个尝试/捕获,当在水合过程中抛出EntityNotFoundException 时,即使实体存在,findBy 也会返回 null,并且它已成功水合。 这是因为相关的引用实体不存在,而 Hibernate 期望它存在

例如,我有两个实体 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;
}

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

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

最好的问候

【讨论】:

  • 同样的问题。在我的情况下,我错误地将引用列的默认值设置为 0 而不是 NULL,这导致连接失败,因此 findById 返回 null/可选空。
  • 我不知道该怎么感谢你,你救了我!非常感谢这个有价值的答案。 EAGER 字段在 DB 上不应为空。
【解决方案2】:

您必须将@RequestBody 更改为@RequestParam。请更新您的控制器代码如下。

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

       return memberService.isExistByUserId(id);
    }

【讨论】:

  • StringUtils.isEmpty(id) 返回 false
  • 对不起。我已经更新了代码。请仔细查看。
【解决方案3】:

我想用@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

【讨论】:

    猜你喜欢
    • 2020-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    • 1970-01-01
    • 2017-08-06
    • 2020-06-20
    • 1970-01-01
    相关资源
    最近更新 更多