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:
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?
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 MyRepositoryCustomImpl 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