使用hibernate我有以下查询
String PQ = "select k from Customer k inner join k.winterSet vs where vs.year = :year";
TypedQuery<Customer> tq = legacyEm.createQuery(PQ,Customer.class);
tq.setParameter("year", DateUtil.getCurrentWinterSeason());
List<Customer> result = tq.getResultList();
客户中的映射
@OneToMany(fetch = FetchType.LAZY, mappedBy = "customer")
private Set<Winter> winterSet = new HashSet<>(0);
和冬天
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "cnr")
private Customer customer;
当我运行此查询时,我只从Customer获得实际在Winter中具有相关行的行,其中属性year与给定参数匹配。到现在为止还挺好。但是,这些Customer对象的winterSet填充了所有相关的Winter对象,而不仅仅是那些在year属性中具有所需值的对象。我怎样才能做到这一点?
答案 0 :(得分:0)
这是完全正常和预期的结果。使用映射,您可以定义实体的结构,包括与其他实体的关系。查询定义了这些实体中的哪些实体。
使用FetchType,您可以部分控制是否获取查询实体的某些持久属性。但是没有机制只填充集合的某些元素。
如果您需要的结果只显示实体中的部分数据,那么您可以创建呈现部分结果的新类,并使用查询和构造函数表达式填充它。
答案 1 :(得分:0)
加入fetch可以解决问题:
字符串PQ =“从客户k内连接FETCH k.winterSet vs中选择k,其中vs.year =:year”;
调试hibernate表示生成的sql包含where子句。但是,由于关系映射为LAZY,因此不会从此查询中填充集合,只会填充Customer对象。稍后访问集合时,会触发加载,但此时,are子句早已消失,并且所有对象都已加载。
但是,当使用“join fetch”(实际上一次从查询中加载所有对象)时,hibernate会从查询的结果集中填充所有内容,因此只有所需的对象出现在集合中。这样做更有效率,只执行了一个查询,之后不需要加载集合中的每个对象,只是为了抛弃大部分对象。
编辑:仅适用于休眠状态,如果修改了结果,可能会产生严重的副作用。见评论。