Question

What is the best practice for creating JPA Repositories?

Right now I have two tables: Media and Ratings.

To find media that is similar a query has to be made to the Rating table to find the interconnections between the different media. This query then returns a list of Media objects.

Should this query be placed in the Rating repository (as it queries the Rating table), or in the Media repository (as it returns a collection of Media objects with the IDs set)?

I have tried searching for best-practices for this particular use-case but haven't found anything relevant.

Update: The SQL query is defined like this:

@Query(value=[SQL query with several joins],nativeQuery=true)
List<Media> mySQLQuery()

it returns a list of mediaId's which can be returned from the function as Media objects.

Was it helpful?

Solution 2

I solved it by creating a custom implementation of the repository, implementing a custom interface.

First I had to declare the interface:

public interface CustomQuery {
    public List<Integer>myCustomQuery(int id)
}

Then I implemented it in my custom repository. The name is important, it has to begin with the name of the repository interface it is extending. My repo is named MediaRepository so I named the custom implementation MediaRepositoryImpl:

@Component
public class MediaRepositoryImpl implements CustomQuery {
    @PersistenceContext
    EntityManager manager;

    public List<Integer>myCustomQuery(int id){
        Query q = manager.createNativeQuery(SQL_QUERY_GOES_HERE);
        List<Integer> ids = new ArratList<Integer>();

        @SuppressWarnings("unchecked")
        List<Integer> result  = q.getResultList();
        for(Integer o : result){
            //process the results and add them to the list
        }
        return list;
    }
}

This way, you can do custom native queries while still keeping the regular Repositories clean. This approach is also easier to test.

OTHER TIPS

Well, probably neither.

You see when you implement a Repository and do for example findAll() you will get a List of all Objects from the Entity used in the Repository creation.

  interface MyRepo implements<Media, Long>....

  myRepo.findAll() will return a List of Media objects.

What you are trying to do is out of scope from a Repository as it acts on only that particular Entity with a finit operations on that particular Entity.

Also it seems to me that Media and Ratings are connected with a OneToMany or ManyToMany, then this definitely should go to a separate DAO method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top