简体   繁体   中英

HQL query to select all unique entities grouped by the parameter value that is in relation to founded entities

So, I'm stuck with the next task. Let's say I have restaurant. It can have a lot of orders, and some of them may have the same IngredientType but with the different expiration time. I need to write HQL that by given restaurantId and list of IngredientTypes will get me a result of the freshest(by expiresAt field in IngredientInfo entity).

Let's say we have restaurant = 1; list of IngedientTypes: POTATO, SALMON. Restaurant has 2 orders:

1: { {POTATO: {expiresAt: 4}, {ORANGE:{expiresAt: 11} } 
2: { {POTATO: {expiresAt: 9}, {SALMON: {expiresAt: 6} }

. Returned result:

[{POTATO: {expiresAt: 4}, {SALMON: {expiresAt: 6}]

I have 4 entities:

@Entity
        @Table(name = "restaurants")
        public class RestaurantEntity {
        
            @Id
            @GeneratedValue(strategy =  GenerationType.IDENTITY)
            Long id;
        
        }

    


@Entity
    @Table(name = "orders")
    public class OrderEntity {

      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      Long id;

      @ManyToOne(fetch = FetchType.EAGER)
      @JoinColumn(name = "restaurantId")
      RestaurantEntity restaurant;

      @OneToMany(mappedBy = "order", fetch = FetchType.EAGER)
      @BatchSize(size = 10)
      List<IngredientEntity> ingredients;

  }

    @Entity
    @Table(name = "ingredients")
    public class IngredientEntity {

    @Id
    @GeneratedValue(strategy =  GenerationType.IDENTITY)
    private Long id;

    @Enumerated(EnumType.STRING)
    private IngredientType ingredientType;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "orderId")
    private OrderEntity order;

    @OneToMany(mappedBy = "ingredient", cascade = CascadeType.ALL)
    @BatchSize(size = 10)
    private List<IngredientInfoEntity> ingredientInfos
}


@Entity
@Table(name = "ingredient_info")
public class IngredientInfoEntity {

    @Id
    @GeneratedValue(strategy =  GenerationType.IDENTITY)
    Long id;

    @ToString.Exclude
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ingredientId")
    IngredientEntity ingredient;

    Instant expriresAt;
}

I did write some query:

@Query(value = " SELECT ie " +
                " FROM OrderEntity oe INNER JOIN IngredientEntity ie " +
                " ON oe.id = ie.order " +
                " WHERE oe.restaurant.id = :restId AND ie.ingredientType in (:ingredientTypes) ")
List<IngredientEntity> findIngredients(String restId, List<IngredientType> ingredientTypes);

It did returns me : [{POTATO: {expiresAt: 9}, {POTATO: {expiresAt: 4}, {SALMON: {expiresAt: 6}]

So, basically I can programmatically filter that list, but my question is it possible to write HQL that will do it?

Yes, it is possible to filter the entity items using HQL(hibernate query language).

Hibernate supports named parameters in its HQL queries. This makes writing HQL queries that accept input from the user easy and you do not have to defend against SQL injection attacks. Following is the simple syntax of using named parameters −

String hql = "FROM Employee E WHERE E.id = :employee_id";
Query query = session.createQuery(hql);
query.setParameter("employee_id",10);
List results = query.list();

you can explore more about HQL here

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