英文:
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 = "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;
}
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 = "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);
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 = "SELECT b FROM Building b" +
" inner join b.contract as c " +
" where c.activeFrom > :date " +
" and b.zipCode = :zipCode";
Just make sure that you joined the second table before filtering
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论