Spring Data JPA – 单独过滤 @OneToMany 关系

huangapple go评论67阅读模式
英文:

Spring Data JPA - filtering @OneToMany relation separately

问题

假设以下内容:

public class Building {
   @Column(nullable = false)
   private String zipCode;

   @OneToMany(mappedBy = "building", fetch = FetchType.LAZY)
   private final Set<Contract> contracts = new HashSet<>();
}

public class Contract {
   @ManyToOne(optional = false, fetch = FetchType.EAGER)
   @JoinColumn(nullable = false, updatable = false)
   private Building building;

   @Column(nullable = false)
   private LocalDate activeFrom;
}

在使用Spring Data JPA存储库的情况下,如何选择所有具有特定zipCode的建筑物,然后对于每个建筑物,选择所有activeFrom早于X的合同?

我能在互联网上找到的所有解决方案似乎都集中在筛选主对象(Building)上,而我希望为子对象(Contract)使用不同的动态条件,并在未找到合同时收到空列表。我明确希望收到没有匹配合同的建筑物。

如果使用DTO/投影而不是实体类,也是可以的。

英文:

Suppose the following:

public class Building {
   @Column(nullable = false)
   private String zipCode;

   @OneToMany(mappedBy = &quot;building&quot;, fetch = FetchType.LAZY)
   private final Set&lt;Contract&gt; contracts = new HashSet&lt;&gt;();
}

public class Contract {
   @ManyToOne(optional = false, fetch = FetchType.EAGER)
   @JoinColumn(nullable = false, updatable = false)
   private Building building;


   @Column(nullable = false)
   private LocalDate activeFrom;
}

Using preferably spring-data-jpa repositories, how can I select all buildings with a certain zipCode, and then for each building, all contracts with an activeFrom earlier than X?

All solutions I can find on the internet seem to focus on filtering the primary object (Building), whereas I'd like to use different dynamic criteria for the child (Contract) and receive an empty list if none are found. I explicitly want to receive Buildings with no matching Contracts.

It is fine if a DTO/projection is used rather than the entity classes.

答案1

得分: 1

我假设你正在寻找一个你可以使用的JpaRepository查询。你可以使用“_”将查询应用于嵌入对象上的字段。

例如,类似这样的内容,findAllByBuilding_ZipCodeAndActiveFromBefore...

英文:

I am going on the assumption you are looking for a JpaRepository query you could use. You can use "_" to apply queries to fields on embedded objects.

For example something like, findAllByBuilding_ZipCodeAndActiveFromBefore...

答案2

得分: 0

以下是已翻译的内容:

你可以使用类似这样的代码按照邮政编码和生效日期进行筛选:

String FIND_ALL_BUILDINGS_BY_ZIP_CODE_AND_ACTIVE_FORM = "SELECT b FROM Building b" +
            " inner join b.contract as c " +
            " with c.activeFrom > :date " +
            " where b.zipCode = :zipCode";

@Query(FIND_ALL_BUILDINGS_BY_ZIP_CODE_AND_ACTIVE_FORM)
List<Group> findAllBuildingsByZipCodeAndActiveFrom(@Param("zipCode") String zipCode, @Param("date") LocalDate date);

这将为您提供至少有一个合同的建筑,其活动日期大于给定日期。

您还可以尝试以下查询:

String FIND_ALL_BUILDINGS_BY_ZIP_CODE_AND_ACTIVE_FORM = "SELECT b FROM Building b" +
            " inner join b.contract as c " +
            " where c.activeFrom > :date " +
            " and b.zipCode = :zipCode";

只需确保在进行筛选之前加入第二个表
英文:

You can use something like this to filter by zipCode and activeFrom

String FIND_ALL_BUILDINGS_BY_ZIP_CODE_AND_ACTIVE_FORM = &quot;SELECT b FROM Building b&quot; +
        &quot; inner join b.contract as c &quot; +
        &quot; with c.activeFrom &gt; :date &quot; +
        &quot; where b.zipCode = :zipCode&quot;;

@Query(FIND_ALL_BUILDINGS_BY_ZIP_CODE_AND_ACTIVE_FORM)
List&lt;Group&gt; findAllBuildingsByZipCodeAndActiveFrom(@Param(&quot;zipCode&quot;) String zipCode, @Param(&quot;date&quot;) LocalDate date);

This will give you a bulding that has atleast one contract that activeFrom > date

Also you can try with this query:

String FIND_ALL_BUILDINGS_BY_ZIP_CODE_AND_ACTIVE_FORM = &quot;SELECT b FROM Building b&quot; +
        &quot; inner join b.contract as c &quot; +
        &quot; where c.activeFrom &gt; :date &quot; +
        &quot; and b.zipCode = :zipCode&quot;;

Just make sure that you joined the second table before filtering

huangapple
  • 本文由 发表于 2020年10月6日 23:00:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/64228479.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定