Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practise when using Querydsl with Spring Data

Using Spring Data nad Querydsl we can just declare repository interface and skip the implementation class. Some methods with a specific name or using @Query annotation and that's all.

But sometimes I'd like to use JPAQuery and define method's body by myself, let's say

@Repository
public class MyRepositoryImpl implements MyRepository {

    @PersistenceContext
    private EntityManager em;

    @Override
    public List<Tuple> someMethod(String arg) {
        JPAQuery query = new JPAQuery(em);
        ...
    }

but this way I would have to implement other MyRepository interface methods, which ruins all Spring Data's advantages!

I can see two options:

  • Declare another interface per each repository and then normally implement it (which doubles number of interfaces)
  • Inject EntityManager into @Service class and implement my custom methods there

I like option #2 more, but as far I as know, in @Service class we should only call repository methods, so it's not a perfect solution as well.

So how does programmers deal with it?

like image 578
pzeszko Avatar asked Aug 19 '15 07:08

pzeszko


People also ask

What is Querydsl in Spring data JPA?

Querydsl is a framework that enables the construction of statically typed SQL-like queries through its fluent API. Spring Data modules offer integration with Querydsl through QuerydslPredicateExecutor .

Is a Querydsl query type for?

Querydsl is an extensive Java framework, which allows for the generation of type-safe queries in a syntax similar to SQL. It currently has a wide range of support for various backends through the use of separate modules including JPA, JDO, SQL, Java collections, RDF, Lucene, Hibernate Search, and MongoDB.

What is Querydsl apt?

The querydsl-apt dependency is an annotation processing tool (APT) — implementation of corresponding Java API that allows processing of annotations in source files before they move on to the compilation stage.

Is Spring data JPA an implementation of the JPA specification?

Spring Data JPA is not an implementation or JPA provider, it's just an abstraction used to significantly reduce the amount of boilerplate code required to implement data access layers for various persistence stores.

How do I use querydsl with spring data JPA?

Getting the Required Dependencies Before we can use Querydsl with Spring Data JPA, we have to add the Querydsl JPA module into our classpath. We can do this by adding the following dependency declaration into the dependenciessection of our pom.xmlfile:

How do I create dynamic SQL queries in spring data?

To achieve dynamic SQL queries, there are several approaches within Spring Data as you can use JPA's Criteria API, use query by example, and the Querydsl integration support (for more information, have a look at the Spring Data documentation ).

Is querydsl easier to use than jdbctemplate?

In this example, we built a Spring boot project to demonstrate Spring Data JPA with Querydsl to allow developers to write type-safe queries in a RDBMS. We also compared it to Spring’s JdbcTemplate and concluded that Querydsl is easier to use. Both Spring Data and Querydsl support nosql database which is not covered in this example.

What is querydslpredicateexecutor in spring data?

QuerydslPredicateExecutor Our Spring Data repository declaration needs to implement QuerydslPredicateExecutor which is Spring Data specific interface. This interface defines various query methods which allow execution of Querydsl for the provided com.querydsl.core.types.Predicate instances. Following is it's snippet:


1 Answers

You should not implement the actual Spring Data repository, instead you have to declare another custom interface where you can put your custom methods.

Let's say you have a MyRepository, defined as

@Repository
public interface MyRepository extends JpaRepository<Tuple, Long> {}

Now you want to add your custom findTuplesByMyArg(), for a sake of purpose you need to create custom repository interface

public interface MyRepositoryCustom {
   List<Tuple> findTuplesByMyArg(String myArg);
}

Afterwards comes the implementation of custom interface

public class MyRepositoryImpl implements MyRepositoryCustom {
    @PersistenceContext
    private EntityManager em;

    @Override
    public List<Tuple> findTuplesByMyArg(String myArg) {
        JPAQuery query = new JPAQuery(em);
        ...
    }    
}

And we need to change MyRepository declaration, so it extends custom repository, so that

@Repository
public interface MyRepository extends JpaRepository<Tuple, Long>, MyRepositoryCustom {}

And you can easily access your findTuplesByMyArg() by injecting MyRepository, e.g.

@Service
public class MyService {
   @Autowired
   private MyRepository myRepository;

   public List<Tuple> retrieveTuples(String myArg) { 
      return myRepository.findTuplesByMyArg(myArg);
   }
}

Pay attention that names are important here (you need to have Impl postfix by default configs in repo implementation).

You can find all needed information here

like image 178
vtor Avatar answered Oct 21 '22 10:10

vtor