当前位置: 首页 > 知识库问答 >
问题:

从嵌套对象列表筛选结果的Hibernate查询

荆弘伟
2023-03-14

作为这个答案的后续(关于方法1),我想更进一步:

我想根据某些标准筛选子对象。我尝试了下面的查询,但它仍然没有筛选出孙实体下的对象

  @Query("select ch from ChildEntity ch "
      + " join ch.parentEntity pr "
      + " join fetch ch.grandChildEntities gc "
      + " where pr.bumId = :bumId and ch.lastExecutionTimestamp in "
      + "( select max(ch1.lastExecutionTimestamp) from ChildEntity ch1 "
      + "join ch1.grandChildEntities gc ON ch1.id = gc.childEntity where "
      + "gc.field1 in ('\"Criteria1\"','\"Criteria2\"','\"Criteria3\"') and " 
      + "gc.field2 = '\"soldout\"'"
      + "ch1.parentEntity = pr group by ch1.c1))")
 List<ChildEntity> findLastExecutedChildFromBumId(@Param("bumId") String bumId);

关联类实体

类关系ParentEntity<1-OneTomany-x>ChildEntity<1-OneTomany-x>GrandChildEntity

@Entity
@Getter
@Setter
@Table(name = "table_parent")
@RequiredArgsConstructor
@NoArgsConstructor
@AllArgsConstructor
public class ParentEntity implements Serializable {
    
   private static final long serialVersionUID = -271246L;
    
   @Id
   @SequenceGenerator(
      name="p_id",
      sequenceName = "p_sequence",
      initialValue = 1,
      allocationSize = 1)
   @GeneratedValue(generator="p_id")
   @Column(name="id", updatable=false, nullable=false)
   private Long id;
    
   @NonNull
   @Column(name ="bum_id", nullable = false, unique = true)
   private String bumId;
    
   @NonNull
   @Column(nullable = false, length = 31)
   private String f1;
    
   @NonNull
   @Column(nullable = false, length = 31)
   private String f2;
    
   @NonNull
   @Column( nullable = false, length = 255)
   @Convert(converter = JpaConverterJson.class)
   private List<String> f3;
    
   @NonNull
   @Column(nullable = false)
   private String f4;
    
   @NonNull
   @Column(name = "es_status", nullable = false, length = 255)
   @Enumerated(EnumType.STRING)
   private ExecutionStatus esStatus;
    
   @JsonManagedReference
   @OneToMany(mappedBy = "parentEntity", cascade = CascadeType.ALL,
       fetch = FetchType.EAGER)
   @Setter(AccessLevel.NONE)
   private List<ChildEntity> childEntities;
    
   public void setChildEntities(List<ChildEntity> childEntities) {
      this.childEntities = childEntities;
      childEntities.forEach(entity -> entity.setParentEntity(this));
   }
}


@Entity
@Getter
@Setter
@Table(name= "table_child")
@NoArgsConstructor
public class ChildEntity implements Serializable {
   private static final long serialVersionUID =  -925587271547L;
    
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;
    
   @JsonBackReference
   @ManyToOne(fetch = FetchType.EAGER )
   @JoinColumn(name = "parent_id")
   private ParentEntity parentEntity;
    
   @Column(name = "c1",nullable = false)
   @NonNull
   @Convert(converter = JpaConverterJson.class)
   private String c1;
    
   @Column(name = "last_exec_status",nullable = false)
   @NonNull
   @Enumerated(EnumType.STRING)
   private ExecutionStatus lastExecStatus;
    
   @Column(name = "c4",nullable = false)
   @NonNull
   private String  c4;
    
   @Column(name = "last_execution_timestamp",nullable = false)
   @NonNull
   private long lastExecutionTimestamp;
    
   @JsonManagedReference
   @NonNull
   @OneToMany(mappedBy = "childEntity", cascade = CascadeType.ALL,
      fetch = FetchType.EAGER)
   @Setter(AccessLevel.NONE)
   private List<GrandChildEntity> grandChildEntities;
    
   public void setGrandChildEntities(List<GrandChildEntity> grandChildEntities) {
      this.grandChildEntities = grandChildEntities;
      grandChildEntities.forEach(entity -> entity.setChildEntity(this));
   }
}


@Entity
@Getter
@Setter
@Table(name="table_grand_child")
@NoArgsConstructor
//@AllArgsConstructor
public class GrandChildEntity implements Serializable {
   private static final long serialVersionUID = -925567241248L;
    
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Long id;
    
   @JsonBackReference
   @ManyToOne(fetch = FetchType.EAGER )
   @JoinColumn(name = "child_entity_id")
   private ChildEntity childEntity;
    
   @Column(name="gc1",nullable = false)
   private String gc1;
    
   @Column(name="gc2",nullable = false)
   private String gc2;
    
   @Column(name="gc3",nullable = false)
   private String gc3;
    
   @Column(name="gc3",nullable = true)
   private List<String> gc3;
}

共有1个答案

鲍俊杰
2023-03-14

筛选联接获取的集合是一个坏主意,因为这会改变“持久状态”,并可能导致实体因此而被删除。我建议您改用DTO方法

我认为这是Blaze-Persistence实体视图的完美用例。

我创建了这个库,以便在JPA模型和自定义接口或抽象类定义的模型之间进行简单的映射,就像Spring Data Projects on Steroids一样。其思想是以您喜欢的方式定义目标结构(域模型),并通过JPQL表达式将属性(getter)映射到实体模型。

使用Blaze-Persistence实体视图,用例的DTO模型可以如下所示:

@EntityView(ChildEntity.class)
public interface ChildEntityDto {
    @IdMapping
    Long getId();
    String getC1();
    ParentEntityDto getParentEntity();
    @Mapping("grandChildEntities[field1 in ('\"Criteria1\"','\"Criteria2\"','\"Criteria3\"') and gc.field2 = '\"soldout\"']")
    Set<GrandChildEntityDto> getGrandChildEntities();

    @EntityView(ParentEntity.class)
    interface ParentEntityDto {
        @IdMapping
        Long getId();
        String getF1();
    }
    @EntityView(GrandChildEntity.class)
    interface GrandChildEntityDto {
        @IdMapping
        Long getId();
        String getGc1();
    }
}

查询是将实体视图应用于查询的问题,最简单的只是按ID查询。

userdto a=entityviewmanager.find(entityManager,userdto.class,id);

Spring数据集成使您可以像使用Spring数据投影一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_us/index.html#spring-data-features

 类似资料:
  • 我正试图找出如何解决这两个问题,我有我的ES 5.6索引。 我需要创建两个单独的脚本过滤器: 1-筛选employee数组大小==3的文档 2-筛选数组第一个元素为“name”==“John”的文档 我试图做一些第一步,但我无法迭代列表。我总是有一个空指针异常错误。

  • 我是Elasticsearch的新手,我试图创建一个过滤器来检索具有特定属性的文档。 属性在映射中定义为嵌套对象,如下所示: 我试图以以下形式执行一个复杂的查询: 这是elasticsearch 2.x。我做错了什么?

  • 我的映射如下所示,我正在对名称和其他属性进行bool应该查询,如下所示,但我需要的是,我希望在响应时根据CustomerId过滤CustomerPrices。每个产品都有相同的CustomerID,所以Eaxample; 因此,根据我查询Product1时,响应应该只有CustomerId:1234的customerPrice 我尝试了以下查询,但这不是过滤嵌套对象。我想它过滤产品对象是有意义的,

  • 假设我们有一个三维的物体列表。 假设我想过滤“l5”,这样如果最里面的列表中的任何元素是奇数,那么整个列表都应该被删除,如果这使得第二级列表为空,那么作为回报应该被删除。 因此,对于给定的示例,在过滤之前,如果: 过滤后,它应该是: 如何使用Java中的流来实现这一点?

  • 我有一个产品集合,每个产品都会有: 价格 属性(例如:大小:xl,s,xxl;颜色:黄,红,蓝;....) 制造商 类别(一个产品可以有多个类别) 此集合在ElasticSearch中索引。现在,当我查询类别A中所有产品的列表时,我还希望获得: 所有产品的价格范围(最小-最大) 所有可能选项和值的列表(大小、颜色和相应的值xl、s、xxl、Yellog、red、blue) 制造商(耐克、阿迪达斯、

  • 设备类型。Java语言 elemetry.java枚举类 我想获取所有DeviceType Id,其DeviceTeletry名称以“System”(字符串)开头。 我做了这样的事情:- 有谁能告诉我如何从中获取DeviceType Id吗?