4

I need to remove the nativeQuery flag from the @Query annotation.
The table structure may change in the future, and code without nativeQuery will make it easier to maintain later.

I have a class Parent that is linked to class Child with the @ManyToMany annotation. Class Child has a field pseudonym that is a value of the String type.

The result of the query needs to be sorted by the String value from class Child, which I have to sort and then concatenate into one String value.

The query without the nativeQuery flag in the @Query annotation works if I do not add an additional sort in the string_agg function:
order by string_agg(c.pseudonym, ',')

If I add additional required sorting as below, an exception occurs

  • order by string_agg(c.pseudonym, ',' order by c.pseudonym)
  • org.hibernate.hql.internal.ast.QuerySyntaxException: expecting CLOSE, found 'order' near line 1, column ...
@Entity
@Getter
@Setter
@Table(name = "parent")
public class Parent {

    @Id
    private Long id;

    private String name;

    @ManyToMany
    @JoinTable(
            name = "parent_child_link",
            joinColumns = {@JoinColumn(name = "parent_id")},
            inverseJoinColumns = {@JoinColumn(name = "child_id")}
    )
    @OrderBy("pseudonym ASC")
    private List<Child> childs = new ArrayList<>();

}
@Entity
@Getter
@Setter
@Table(name = "child")
public class Child {

    @Id
    private Long id;

    private String pseudonym;

    @ManyToMany(mappedBy = "childs")
    private Set<Parent> parents = new HashSet<>();

}
public interface ParentRepository extends JpaRepository<Parent, Long> {

        @Query(nativeQuery = true, value =
            "select p.*" +
                    " from parent p" +
                    " left join parent_child_link link on p.id = link.parent_id" +
                    " left join child c on link.child_id = c.id" +
                    " where p.name = :name" +
                    " group by (p.id)" +
                    " order by string_agg(c.pseudonym, ',' order by c.pseudonym)")
    Page<Parent> find(@Param("name") String name, Pageable pageable);

}
2
  • If you want to use native functionalities which are not supported by HQL/JPQL, you'll have to write native queries. If you would want to limit the result set, you would also end up with native query as LIMIT is not supported in HQL/JPQL. Commented Jun 14, 2021 at 19:53
  • The current native query visible in the @Query annotation works fine, and in the console (using the p6spy tool) at the end of the query you can see an added entry limiting the number of results ... group by (p.id) order by string_agg (c.pseudonym, ',' order by c.pseudonym) limit 20. Commented Jun 15, 2021 at 4:43

1 Answer 1

1

Please try with nested query:

select p.*
from (
    select p, string_agg(c.pseudonym, ',' order by c.pseudonym) ord
    from parent p
    left join parent_child_link link on p.id = link.parent_id
    left join child c on link.child_id = c.id
    where p.name = :name
    group by (p.id)
) inn(p, ord)
order by ord

or:

select p.*
from(
    select p, c.pseudonym
    from parent p
    left join parent_child_link link on p.id = link.parent_id
    left join child c on link.child_id = c.id
    where p.name = :name
    order by p, pseudonym
) inn(p, pseudonym)
group by p.id
order by string_agg(pseudonym, ',')
Sign up to request clarification or add additional context in comments.

2 Comments

The above queries will not help to remove the nativeQuery flag from the @Query annotation.
@GrzegorzKawalec of course it won't... You're using postgres specific functionality...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.