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.
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 likeUPPER(x.firstame) = UPPER(?1)
.By default when you have
findByProperty
method, the match is exact, so if you want to haveLIKE
functionality you would use method namefindByFirstnameLike
which would in turn translate into conditionwhere 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.