简体   繁体   中英

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.

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

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

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

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, ie :

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.

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

   return member.isPresent();
}

Please update your MemberService code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM