33

I was looking at docs of spring data, and didn't find a reasons to use methods read...By, get...By instead of find...By (as it usually done). Please clarify:

  • what does this methods do?
  • or what is purpose of this methods is?
  • In what cases better use this methods?
  • what is the difference between them?

Could you write an example of query..By method?

manish
  • 19,695
  • 5
  • 67
  • 91
Mykhailo Dmytriakha
  • 628
  • 1
  • 7
  • 13
  • 7
    There is no difference between these four approaches. These have been provided as options to suit individual preferences as different developers may have different preferences for how they would like to name their accessor methods. `Foo findByName (String name)`, `Foo getByName (String name)`, `Foo queryByName (String name)` and `Foo readByName (String name)` are all equivalent - they will find a `Foo` with a name matching the value passed as the `name` parameter. – manish Oct 05 '16 at 11:44

4 Answers4

46

EDIT:
This answer covers Spring query creation mechanism described in docs
If you are looking for the differences between concrete methods findById(..) vs getById(..) you can find nice desciption here (thanks to @smile comment)

ORIGINAL ANSWER:
I don't know how about other subprojects, but for Spring Data JPA (1.10.2) these methods will work as aliases. Each method invocation will generate identical criteria query (and identical SQL query).

Internally there is no distinction between these prefixes. It's used only for query pattern matching:

private static final String QUERY_PATTERN = "find|read|get|query|stream";

https://github.com/spring-projects/spring-data-commons/blob/8bc022ebd7097b921ae1ef6c87f0ae9fc05bba5f/src/main/java/org/springframework/data/repository/query/parser/PartTree.java#L54

The same approach is used for remove...By vs delete...By methods:

private static final String DELETE_PATTERN = "delete|remove";
Maciej Marczuk
  • 3,593
  • 29
  • 28
6

I think this will help you to understand..

The difference between the two interfaces lies in the semantic of their methods. The CRUD repository “finds” something whereas the JPA repository “gets” something. While “find” might lead to no result at all, “get” will always return something – otherwise the JPA repository throws an exception.

source: https://tuhrig.de/find-vs-get/

You can see this post also. https://softwareengineering.stackexchange.com/questions/182113/how-and-why-to-decide-between-naming-methods-with-get-and-find-prefixes

emon
  • 1,629
  • 1
  • 17
  • 18
2

I don't know how Spring implemented this in the past, but at least currently it's not correct that they are the same (just alias).

(This part above is incorrect from the original accepted)

Spring JPA is a layer on top of JPA. Therefore each of these operations is mapped to a Standard JPA operation:

findById(id) -> [on JPA] entityManager.find

Whilst, getOne(id) -> [JPA] entityManager.getReference

So what's the difference on JPA then?

entityManager.find goes directly to the DB, executes the query and returns all mapped columns to the memory. Pretty straightforward.

entityManager.getReference is less used (it's less known). It's sort of a lazy find.
That is, it doesn't go directly to the DB. It only goes when the data is used. Its main target is when you just want a reference to some entity, but you won't use the entity (the values of the columns).

For instance:

class Customer {
    Long id;
    ... many other fields
}

class Order {

    Customer customer;
    // ... other
}

You want to save a new Order:

var order = new Order();

// Opt 1 (find): goes directly to DB and loads everything from this customer. Even tough we don't need it all.  
// order.setCustomer(repo.findById(123L));  
// ...    
// Opt 2 (get): Won't go to DB at this point - but rather get a reference to a specific id   
// When saving, may throw exception if customer with given id doesn't exist  
order.setCustomer(repo.getOne(123L));  
orderRepo.saveOrUpdate(order);

You can check a whole article explaining the diff, and better about getReference here: https://vladmihalcea.com/entitymanager-find-getreference-jpa/.
The article isn't about Spring, but again, Spring JPA just follows JPA.

RicardoS
  • 2,088
  • 1
  • 21
  • 22
  • Question refers to query creation mechanism (docs.spring.io/spring-data/jpa/docs/current/reference/html/…). These methods you mention are not part of that mechanism, these methods have concrete implementations and have a different purpose – Maciej Marczuk Mar 17 '23 at 18:05
2

It seems to me that accepted answer is incorrect. It is different internally in both cases:

  • getById() returns a reference to the entity with the given identifier. It invokes EntityManager.getReference() and returns a lazy proxy. So when you are out of transaction with this response - you will get LazyInitializationException when trying to get lazy fields.
  • findById() fetches real object from database.
Zon
  • 18,610
  • 7
  • 91
  • 99
  • Question refers to query creation mechanism (https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-creation). These methods you mention are not part of that mechanism, they are concrete implementations that have a different purpose. – Maciej Marczuk Mar 17 '23 at 18:03
  • See also https://stackoverflow.com/a/69109941/1112963 – Zon Jul 07 '23 at 07:27