Spring JPA: Under the covers
Tags: java, springboot2, springdatajpa, database
Published: 2020-08-10 03:29:20

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4ddj2q8o4k3o5hxt0w9n.jpeg)

#Spring Data JPA

In the early days, the DAO layer used to consist or still has a lot of boilerplate code which makes it cumbersome to implement. Spring Data JPA, part of the spring-data framework, helps to reduce this boilerplate code and makes it easy for a developer to focus on what's really important.

Reduced boilerplate means reduced code and artifacts to define and maintain. Spring JPA takes this to another level wherein you can replace the DAO layer with a configuration in a property file. The level of abstractions JPA provides helps the developer to only have an interface artifact to maintain.

To start working with Spring JPA a DAO interface must extend JPARepository. Just my extending this interface the developer has tons of methods already implemented and ready to use.
```
public interface FooRepository extends JpaRepository<Foo, Long> { 
}
```
#### But how does Spring JPA work!
There are many ways you can leverage the power of Spring JPA, We will discuss Query creation here.

#####There are two ways to implement query creation:
1. Automatic Custom Queries
2. Manual Custom Queries

#### 1. Automatic Custom Queries:

When we extend the JPARepository Spring scans every method in the interface and tries to parse it to generate queries. It stripes the prefixes such as **find...By**, **read...By**, **count...By**, **query...By**, **get...By**, from the method, and starts parsing the rest of it.
```
public interface FooRepository extends JpaRepository<Foo, Long> { 
    
    public Optional<Foo> findByName(String name); 

}
```


The first **'By'** acts as a delimiter to indicate the start of the query. We can add conditions on the entity properties and concatenate them with **'And'** or **'Or'**. we can also add a Distinct clause to set a distinct flag.

```
public interface FooRepository extends JpaRepository<Foo, Long> { 
    
    public Optional<Foo> findByFirstnameAndLastname(String firstname, String lastname); 

    public List<Foo> findByFirstnameOrLastname(String firstname, String lastname);

    public List<Foo> findDistinctByLastname(String lastname);
}

```
 
**_" Expressions are usually property traversal combined with operators that can be concatenated. We can combine properties expression with 'And' and 'Or'. There are other operators such as 'Between', 'LessThan', 'GreaterThan', 'Like' for property expression." :- Spring Docs_**

The above line defines the automatic query creation perfectly.

##### Property Expression
Property expression can only refer to a direct property of the managed entity. At query creation time, you already make sure that the parsed property is a property of managed domain class 


#### 2. Manual custom Queries

If we still wish to write some custom query to refine our result and to achieve the desired set of records which cannot be done using the Automatic query creation we are free to write custom JPQL queries.

We can define the custom queries using the **@Query** annotation.

```
public interface FooRepository extends JpaRepository<Foo, Long> { 
  
    @Query("SELECT f FROM Foo f WHERE LOWER(f.name) = LOWER(:name)")
    Foo retrieveByName(@Param("name") String name);

}
```
Once we use the **@Query** annotation the method name doesn't
matter as the method name won't be parsed.

#### Conclusion
Thanks to the Spring Data JPA team we can implement the DAO layer effortlessly and focus on what matters. This blog is just a gist of what Spring Data JPA has to offer, there is a lot more we can do with the JPA implementation