Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Spring Data JPA work internally

I was going through Spring Data JPA Tutorial. I am confused on how does this framework work internally. Let me state specific scenario

There was specific code

/**
 * Custom finder
 */
public List<Location> getLocationByStateName(String name) {
    @SuppressWarnings("unchecked")
    List<Location> locs = entityManager
        .createQuery("select l from Location l where l.state like :state")
        .setParameter("state", name + "%").getResultList(); // note
        return locs;
}

This was simply replaced by following interface

@Repository
public interface LocationJPARepository extends JpaRepository<Location, Long> {
    List<Location> findByStateLike(String stateName);
}

And corresponding test case worked fine

@Test
public void testFindWithLike() throws Exception {
   List<Location> locs = locationRepository.getLocationByStateName("New");
   assertEquals(4, locs.size());
}

New test case

@Test
public void testFindWithLike() throws Exception {
   List<Location> locs = locationJPARepository.findByStateLike("New");
   assertEquals(4, locs.size());
}

My question

  • How does framework know if i am looking for exact match using = or partial match using SQL like operator (it cant be method name ?)
  • if it somehow decide I am looking for partial match then still there are sub options ... like name% or %name or %name% …
  • Also how it decides case is important in like ? ( i can have case-insensitive by using SQL like with toUpper() i.e. by comparing everything in upper case )
  • (added ques) is there a way i can check the EXACT SQL in log some where ??

Hope i was able to explain my question properly. Let me know if i need to add in more clarity.

like image 962
Lav Avatar asked Sep 20 '15 12:09

Lav


1 Answers

I recommend to take a look at Query Creation section of the reference guide. It explains the rules pretty clearly.

For instance when you want to find User by first name and ignore case, you would use method name like findByFirstnameIgnoreCase which would translate into condition like UPPER(x.firstame) = UPPER(?1).

By default when you have findByProperty method, the match is exact, so if you want to have LIKE functionality you would use method name findByFirstnameLike which would in turn translate into condition where x.firstname like ?1.

You can combine these keywords, but it can get a little crazy. Personally I prefer using @Query annotation for more complicated queries to avoid super long repository method names.

like image 64
Bohuslav Burghardt Avatar answered Sep 19 '22 15:09

Bohuslav Burghardt