Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 780
Jin-guk Park Avatar asked Jul 16 '19 03:07

Jin-guk Park


People also ask

What does findById return in JPA?

Its findById method retrieves an entity by its id. The return value is Optional<T> . Optional<T> is a container object which may or may not contain a non-null value. If a value is present, isPresent returns true and get returns the value.

Does JPA return null or empty list?

Spring JPA Query returns Null instead of List.

What is the difference between findById and getById?

As a consequence, findById() returns the actual object and getById returns a reference of the entity.

Should I use JpaRepository or CrudRepository?

Crud Repository doesn't provide methods for implementing pagination and sorting. JpaRepository ties your repositories to the JPA persistence technology so it should be avoided. We should use CrudRepository or PagingAndSortingRepository depending on whether you need sorting and paging or not.


1 Answers

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

like image 144
Kevin Guanche Darias Avatar answered Sep 20 '22 16:09

Kevin Guanche Darias