'JPA Repository.findById() returns null but the value is exist on db
I'm developing Spring boot project, using JPA.
What I wanna know is repository.findById(id) method returns null, whereas data is available in the DB.
Functions save()
and findAll()
are working fine. When I ran the same code on junit test environment, but it completely worked. If the data is hard coded, like memberRepository.findById("M001");
, it working fine.
Entity
@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.....
Controller
@ResponseBody
@RequestMapping(value="/checkIdDuplicate", method=RequestMethod.POST)
public boolean checkIdDuplicate(@RequestBody String id) {
return memberService.isExistByUserId(id);
}
MemberService
public boolean isExistByUserId(String id) {
Optional<DfMember> member = memberRepository.findById(id);
return member.isPresent();
}
Repository
public interface MemberRepository extends CrudRepository<DfMember, String> {
}
Should return Member Object but it's null.
Solution 1:[1]
You have to change @RequestBody
to @RequestParam
. Please update your controller code as below.
@ResponseBody
@RequestMapping(value="/checkIdDuplicate", method=RequestMethod.POST)
public boolean checkIdDuplicate(@RequestParam String id) {
return memberService.isExistByUserId(id);
}
Solution 2:[2]
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
For example I have two entities Unit and Improvement where I store an unit with id 5 to have an improvement with id 0
(which doesn't exists), then unitRepository.findById()
returns null, instead of the Unit entity with 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;
}
The reason this happened was because an import script used 0 as value for the improvement_id instead of the original NULL.
Hint: Becareful with disabling Foreign Key checks in import scritps
Best regards
Solution 3:[3]
I would like to add something with @Alexpandiyan answer. Instead of first finding record by Id and checking if it is present or not. You can directly check in database if id exists or not by using predefined function existsById
like below.
public interface MemberRepository extends CrudRepository<DfMember, String> {
boolean existsById(String id);
}
Updated member service function memberService.isExistByUser()
.
public boolean isExistByUserId(String id) {
return memberRepository.existsById(id);
}
See documentation https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#new-features.1-11-0
Solution 4:[4]
This occurred to me because of a script which was inserting data (while disabling foreign key checks), and one of the referenced ID was not existing in the parent table, i.e. :
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;
The Jane Doe
record references a target primary key value (company_id
=2
) that does not exist in the company
table.
In that case JPA's findById
does not return any record even if it exists.
Fixing data intergrity solves the problem.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Kevin Guanche Darias |
Solution 3 | Alexpandiyan Chokkan |
Solution 4 | Yann39 |