我使用Spring Boot1.5.3。发布
,对于我来说,不清楚如何根据嵌套对象的属性对其进行排序,这些嵌套对象具有不同的
和规范
,因为:
原因:org。postgresql。util。PSQLException:错误:对于SELECT DISTINCT,ORDER BY表达式必须出现在SELECT列表中
Spring Data JPA生成了错误的查询。
让我们看一个小例子:
@Data
@Entity
@Table(name = "vehicle")
public class Vehicle implements Serializable {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;
@ManyToOne
@JoinColumn(name = "vehicle_type_id")
private VehicleType vehicleType;
@ManyToOne
@JoinColumn(name = "vehicle_brand_id")
private VehicleBrand vehicleBrand;
}
我们有Vehicle
类和嵌套对象VehicleType
和VehicleBrand
。
@Data
@Entity
@Table(name = "vehicle_brand")
public class VehicleBrand implements Serializable {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@ManyToOne
@JoinColumn(name = "vehicle_model_id")
private VehicleModel model;
}
类车辆品牌
还包含车辆模型
。
@Data
@Entity
@Table(name = "vehicle_model")
public class VehicleModel implements Serializable {
@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;
@Column(name = "name")
private String name;
}
现在,我想用JPA规范创建一个查询,并按照
“vehicleBrand.name”
进行排序:
public List<Vehicle> findAll() {
Specification<Vehicle> spec = Specifications.where(
(root, criteriaQuery, criteriaBuilder) -> {
criteriaQuery.distinct(true);
return null;
}
);
return vehicleRepository.findAll(spec, new Sort("vehicleBrand.name"));
}
Spring Data JPA生成以下查询:
select
distinct vehicle0_.id as id1_0_,
vehicle0_.gas_type as gas_type2_0_,
vehicle0_.vehicle_brand_id as vehicle_4_0_,
vehicle0_.vehicle_type_id as vehicle_5_0_,
vehicle0_.year_of_issue as year_of_3_0_
from
vehicle vehicle0_
left outer join
vehicle_brand vehiclebra1_
on vehicle0_.vehicle_brand_id=vehiclebra1_.id
order by
vehiclebra1_.name asc
而且它完全不起作用,因为:
在这种情况下,按表达式“VEHICLEBRA1_uu1.NAME”排序必须在结果列表中;SQL语句
为了解决这个问题,我们必须在我们的
规范中获取
车辆品牌
:
public List<Vehicle> findAll() {
Specification<Vehicle> spec = Specifications.where(
(root, criteriaQuery, criteriaBuilder) -> {
criteriaQuery.distinct(true);
root.fetch("vehicleBrand", JoinType.LEFT); //note that JoinType.INNER doesn't work in that case
return null;
}
);
return vehicleRepository.findAll(spec, new Sort("vehicleBrand.name"));
}
Spring Data JPA生成以下查询:
select
distinct vehicle0_.id as id1_0_0_,
vehiclebra1_.id as id1_1_1_,
vehicle0_.gas_type as gas_type2_0_0_,
vehicle0_.vehicle_brand_id as vehicle_4_0_0_,
vehicle0_.vehicle_type_id as vehicle_5_0_0_,
vehicle0_.year_of_issue as year_of_3_0_0_,
vehiclebra1_.vehicle_model_id as vehicle_3_1_1_,
vehiclebra1_.name as name2_1_1_
from
vehicle vehicle0_
left outer join
vehicle_brand vehiclebra1_
on vehicle0_.vehicle_brand_id=vehiclebra1_.id
order by
vehiclebra1_.name asc
现在它可以工作了,因为我们看到了
vehiclebra1_1;。选择部分中的名称
。
但是,如果我需要排序
车辆Brand.model.name
?
我做了一个额外的获取
,但它不起作用:
public List<Vehicle> findAll() {
Specification<Vehicle> spec = Specifications.where(
(root, criteriaQuery, criteriaBuilder) -> {
criteriaQuery.distinct(true);
root.fetch("vehicleBrand", JoinType.LEFT).fetch("model", JoinType.LEFT);
return null;
}
);
return vehicleRepository.findAll(spec, new Sort("vehicleBrand.model.name"));
}
它生成以下查询:
select
distinct vehicle0_.id as id1_0_0_,
vehiclebra1_.id as id1_1_1_,
vehiclemod2_.id as id1_2_2_,
vehicle0_.gas_type as gas_type2_0_0_,
vehicle0_.vehicle_brand_id as vehicle_4_0_0_,
vehicle0_.vehicle_type_id as vehicle_5_0_0_,
vehicle0_.year_of_issue as year_of_3_0_0_,
vehiclebra1_.vehicle_model_id as vehicle_3_1_1_,
vehiclebra1_.name as name2_1_1_,
vehiclemod2_.name as name2_2_2_
from
vehicle vehicle0_
left outer join
vehicle_brand vehiclebra1_
on vehicle0_.vehicle_brand_id=vehiclebra1_.id
left outer join
vehicle_model vehiclemod2_
on vehiclebra1_.vehicle_model_id=vehiclemod2_.id cross
join
vehicle_model vehiclemod4_
where
vehiclebra1_.vehicle_model_id=vehiclemod4_.id
order by
vehiclemod4_.name asc
它不起作用是因为:
在这种情况下,按表达式“VEHICLEMOD4_U4.NAME”排序必须在结果列表中;SQL语句
看看我们是如何选择车辆模块的。姓名
但通过vehiclemod4_2;订购。名称
。
我试图直接在
规范中进行排序,但也不起作用:
Specification<Vehicle> spec = Specifications.where(
(root, criteriaQuery, criteriaBuilder) -> {
criteriaQuery.distinct(true);
root.fetch("vehicleBrand", JoinType.LEFT).fetch("model", JoinType.LEFT);
criteriaQuery.orderBy(criteriaBuilder.asc(root.join("vehicleBrand", JoinType.LEFT).join("model", JoinType.LEFT).get("name")));
return null;
}
);
我应该怎么做才能让JPA生成正确的查询,这样我就可以根据嵌套的对象进行排序了?将Spring Boot的版本从
1.5.3升级是否有意义。RELEASE
到2
?
谢谢。
这里有一个小秘密:您根本不需要使用Sort
参数。
只需使用CriteriaQuery。订购人
:
Specification<Vehicle> spec = Specifications.where(
(root, criteriaQuery, criteriaBuilder) -> {
criteriaQuery.distinct(true);
var model = root.fetch("vehicleBrand", JoinType.LEFT).fetch("model", JoinType.LEFT);
criteriaQuery.orderBy(criteriaBuilder.asc(model.get("name"));
return null;
}
);
return vehicleRepository.findAll(spec));
Sort
参数很可能是在您的场景中添加额外连接的原因。
我使用jhipster标准和jpa规范来实现进行研究的endpoint。 嗯,这是工作,但继续给我发送副本。 这个模型有一些前提条件 公司与前置站的关系 这是我用来创建规范的CompanySpecification类,我把它交给了存储库 这是我使用它的服务方法 我在CriteriaQuery中发现了一个不同的方法,但我真的不知道如何在我的规范中添加它。 请帮帮忙!
问题内容: 我想按属性排序。这是我的代码… 现在我想按属性将其排序,例如在另一个活动中。但是我不知道该怎么做。有人知道吗? 问题答案: 您需要实现,例如: 然后像这样排序:
问题内容: 比方说你有一个的对象。 如果它们都具有int GoalScored变量,则如何排序?你如何按GoalScored排序? 问题答案: 你可以使用Collections.sort自定义Comparator 。 比较部分也可以这样写: 或者,你可以制作。这定义了所有对象的自然顺序。使用a 更灵活,因为不同的实现可以按名称,年龄等进行排序。
我正在使用一个JPA查询,它使用一个规范来检索实体。当我执行查询时,我得到了一个错误: 组织。springframework。数据映射。PropertyReferenceException:找不到类型任务的属性名称! 我已经查看了之前在该网站上提出的类似问题的答案 当我使用调试器逐步检查代码时,条件生成器中的扩展路径将返回嵌入的ID类,但当规范实际用于查询时,该属性似乎正在应用于基本实体类。 我是
我正在尝试使用Spring数据JPA Specification来查询数据,但这里有一些问题。Java代码如下: 当我注释代码“收件人NoticeJoin.fetch(UserNoticeEntity_. user, JoinType. INNER);”时,它工作正常,但当我取消注释时,我会得到错误: 所以,我想知道使用规范方式是否支持连接获取,或者我的代码有问题。我知道使用@Query(“一些h
问题内容: 如果我有一个JavaScript对象,例如: 有没有一种方法可以基于值对属性进行排序?这样我最终 问题答案: 将它们移动到一个数组,对该数组进行排序,然后将其用于您的目的。这是一个解决方案: 拥有数组后,您可以按自己喜欢的顺序从数组中重建对象,从而完全实现了您打算要做的事情。在我所知道的所有浏览器中都可以使用,但这取决于实现的怪癖,并且可能随时中断。您永远不应假设JavaScript对