Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data JPA JPQL queries on parent interface

Say I have a @MappedSuperClass like this:

@MappedSuperclass
public abstract class Rating
{
    @Id
    private Long id;

    @Column(name="USER_ID")
    private Long userId;

    private int rating;
    ...

With a concrete child entity like this

@Entity
@Table(name="ACTIVITY_RATING")
public class ActivityRating extends Rating
{
    private Long activitySpecificData;
    ...

Then there is a Spring Data JPA repository like this:

@NoRepositoryBean
public interface RatingRepository<R extends Rating> extends JpaRepository<R, ID>
{
    public List<R> findByUserId(Long userId);
    ...

and this:

public interface ActivityRatingRepository extends RatingRepository<ActivityRating>
{

}

This all works great and I can call findByUserId() on any of specific rating repositories that extend RatingRepository. I am now wanting to write some JPQL in the RatingRepository that all the child interfaces can inherit. I just don't know what (or if it's even possible) to put after the FROM in the query. For example:

@Query("SELECT NEW com.foo.RatingCountVo(e.rating, COUNT(e.rating)) FROM ??????? e GROUP BY e.rating")
public List<RatingCountVo> getRatingCounts();

I can add this method to each of the individual repositories that extend RatingRepository but everything would be exactly the same except for the specific entity name. If I want to change the query, I'd then have to go to all the child repositories and update them individually. I really want the query to live in the parent class and not be duplicated. Is there any way to accomplish this?

I'm currently using spring-data-jpa 1.7.2 and eclipselink 2.5.2. I'm not necessarily opposed to switching to newer versions if necessary.

like image 251
dnc253 Avatar asked Oct 15 '25 11:10

dnc253


1 Answers

Will it work if you will split query into 3 parts: start, entity and end of query? Than, if it'll work, in each interface you define constant like

String ENTITY = "ActivityRating";

And then you can use it like

@Query(RatingRepository.QUERY_START + ENTITY + RatingRepository.QUERY_END)
List<RatingCountVo> getRatingCounts();

BTW, there is no need to define public modifier in interface.

UPDATE: here is described another way:

@Query("SELECT NEW com.foo.RatingCountVo(e.rating, COUNT(e.rating)) FROM #{#entityName} e GROUP BY e.rating
like image 88
asm0dey Avatar answered Oct 16 '25 23:10

asm0dey