我正在开发 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> {
}
应该返回成员对象,但它是空的。
虽然OP已经解决了他的问题,但我必须将我的答案添加到同一问题,但原因不同,因为我确信经过数小时的调试后我在Hibernate的源代码中发现会有帮助(5.4.18 ) 一个 try/catch,当在水合过程中抛出
EntityNotFoundException
时,findBy 返回 null,即使实体存在,并且水合成功。 这是因为相关引用实体不存在并且 Hibernate 期望它存在
例如,我有两个实体 Unit 和 Improvement,其中我存储一个 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。
提示:在导入脚本中禁用外键检查时要小心
致以诚挚的问候
我想用@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
您必须将
@RequestBody
更改为 @RequestParam
。请按如下所示更新您的控制器代码。
@ResponseBody
@RequestMapping(value="/checkIdDuplicate", method=RequestMethod.POST)
public boolean checkIdDuplicate(@RequestParam String id) {
return memberService.isExistByUserId(id);
}
我遇到这种情况是因为一个脚本正在插入数据(同时禁用外键检查),并且父表中不存在引用的 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
不会返回任何记录,即使它存在。
修复数据完整性可以解决问题。
public boolean isExistByUserId(String id)
{
Optional<DfMember>member = Optional.ofNullable(memberRepository.findById(id).orElse(new DfMember()));
return member.isPresent();
}
请更新您的会员服务代码。