简体   繁体   中英

order by a field in a filtered OneToMany relation using JPA Specification ( CriteriaQuery CriteriaBuilder )

What I want to achieve: order a list of Book entities on a @OneToMany relation, on a specific attribute after applying a condition.

@Entity
public class Book{

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "bookId")
  private Long id;

  @OneToMany(mappedBy = "entity", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
      Set<RowOrder> orders;
}

@Entity
public class RowOrder {

  @EmbeddedId
  private RowOrderId id;

  @ManyToOne
  @MapsId("entityId")
  @JoinColumn(name = "entity_id")
  private Book entity; 

  @ManyToOne
  @MapsId("userId")
  @JoinColumn(name = "user_id")
  private User user;

  @Column(name = "entity_order")
  private Long order;
}
@Entity
public class User {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "userId")
  private Long id;
}

I want to order books by book.orders.order in which order.userId == aUser.id .

I am using jpa.domain.Specification to filter in which I want to apply this order.



@AllArgsConstructor
public class BookSpecification implements Specification<Book> {

  ...

  @Override
  public Predicate toPredicate(Root<Task> root, CriteriaQuery<?> criteriaQuery,
      CriteriaBuilder criteriaBuilder) {

 ...

aUser ; // this the user entity in which i want to apply on the relation

 criteriaQuery.orderBy(criteriaBuilder.asc(
        root.join("orders", JoinType.LEFT) // <--- how to filter this with, WHERE row_order.user_id = aUser.id
            .get("order")) 
    );

   ...
}
  • how can I achieve this?
  • can I write some native sql when using CriteriaBuilder ? if so how can I write the OrderBy cause in my case with a natvie sql?

this how we solved it:

      Join<Book, RowOrder> books_orders_join = root.join("orders", JoinType.LEFT);
      Join<Join<Book, RowOrder>, User> books_orders_users_join = books_orders_join
          .join("user", JoinType.LEFT);

      predicates
          .add(
              criteriaBuilder
                  .equal(books_orders_users_join.get("id"), aUser.getId()));

      criteriaQuery.orderBy(criteriaBuilder.asc(books_orders_join.get("order")));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM