JPA 标准规范 - 按 returns 所有列进行多选
JPA Criteria Specification - multiselect with group by returns all columns
我正在尝试使用 JPA 规范和标准在 table 上实现基本分组。我使用 query.multiselect 并提供了一栏。但是,在执行期间,正在构建 SQL 查询以获取所有列。从理论上讲,一切看起来都不错。不确定我哪里出错了。
以下是服务方式
public List<POJO> fetchInwardnventoryGroupByUsingSpec() throws ParseException
{
Specification<InwardInventory> spec = findAllGroupBy();
List<POJO> iiData = inwardInventoryRepo.findAll(spec);
return iiData;
}
public static Specification<InwardInventory> findAllGroupBy()
{
return new Specification<InwardInventory>()
{
@Override
public Predicate toPredicate(Root<InwardInventory> root, CriteriaQuery<?> query, CriteriaBuilder cb)
{
query.multiselect(root.get(InwardInventory_.VEHICLE_NO),cb.count(root));
query.groupBy(root.get(InwardInventory_.VEHICLE_NO));
return query.getRestriction();
}
};
}
下面是hibernate
生成的SQL
/* select
generatedAlias0
from
InwardInventory as generatedAlias0
where
generatedAlias0.warehouse.warehouseName like :param0
group by
generatedAlias0.vehicleNo */ select
inwardinve0_.inwardid as inwardid1_13_,
inwardinve0_.created_at as created_2_13_,
inwardinve0_.is_deleted as is_delet3_13_,
inwardinve0_.updated_at as updated_4_13_,
inwardinve0_.additional_info as addition5_13_,
inwardinve0_.date as date6_13_,
inwardinve0_.invoice_received as invoice_7_13_,
inwardinve0_.our_slip_no as our_slip8_13_,
inwardinve0_.contact_id as contact11_13_,
inwardinve0_.supplier_slip_no as supplier9_13_,
inwardinve0_.vehicle_no as vehicle10_13_,
inwardinve0_.warehouse_id as warehou12_13_
from
inward_inventory inwardinve0_ cross
join
warehouse warehouse1_
where
(
inwardinve0_.is_deleted = 'false'
)
and inwardinve0_.warehouse_id=warehouse1_.warehouse_id
and (
warehouse1_.warehouse_name like ?
)
group by
inwardinve0_.vehicle_no
下面是实体class
@Entity
@Table(name = "inward_inventory")
@Audited
@Where(clause = ReusableFields.SOFT_DELETED_CLAUSE)
public class InwardInventory extends ReusableFields implements Cloneable
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="inwardid")
Long inwardid;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd")
@Column(nullable = false)
@NonNull
Date date;
@NonNull
String vehicleNo;
String supplierSlipNo;
String ourSlipNo;
@ManyToMany(fetch=FetchType.EAGER,cascade = CascadeType.ALL)
@JoinTable(name = "inwardinventory_entry", joinColumns = {
@JoinColumn(name = "inwardid", referencedColumnName = "inwardid") }, inverseJoinColumns = {
@JoinColumn(name = "entryId", referencedColumnName = "entryId") })
Set<InwardOutwardList> inwardOutwardList = new HashSet<>();;
@ManyToOne(fetch=FetchType.LAZY,cascade = CascadeType.ALL)
@JoinColumn(name="warehouse_id",nullable=false)
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
Warehouse warehouse;
@ManyToOne(fetch=FetchType.LAZY,cascade = CascadeType.ALL)
@JoinColumn(name="contactId",nullable=false)
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
Supplier supplier;
String additionalInfo;
@NonNull
@Column(nullable = false)
Boolean invoiceReceived;
//getter/setter
}
经过几天的努力终于知道这是一个已知问题
https://jira.spring.io/browse/DATAJPA-1532
因此,我通过自动装配实体管理器处理它,然后创建所有必需的谓词和查询。然后调用 getResults() 而不是 findall()
@Autowired
EntityManager entityManager;
public List<Model> getResults() throws ParseException
{
CriteriaQuery<Model> query = modelSpecification.getSpecQuery();
List<Model> allData = entityManager.createQuery(query).getResultList();
return allData;
}
我正在尝试使用 JPA 规范和标准在 table 上实现基本分组。我使用 query.multiselect 并提供了一栏。但是,在执行期间,正在构建 SQL 查询以获取所有列。从理论上讲,一切看起来都不错。不确定我哪里出错了。
以下是服务方式
public List<POJO> fetchInwardnventoryGroupByUsingSpec() throws ParseException
{
Specification<InwardInventory> spec = findAllGroupBy();
List<POJO> iiData = inwardInventoryRepo.findAll(spec);
return iiData;
}
public static Specification<InwardInventory> findAllGroupBy()
{
return new Specification<InwardInventory>()
{
@Override
public Predicate toPredicate(Root<InwardInventory> root, CriteriaQuery<?> query, CriteriaBuilder cb)
{
query.multiselect(root.get(InwardInventory_.VEHICLE_NO),cb.count(root));
query.groupBy(root.get(InwardInventory_.VEHICLE_NO));
return query.getRestriction();
}
};
}
下面是hibernate
生成的SQL/* select
generatedAlias0
from
InwardInventory as generatedAlias0
where
generatedAlias0.warehouse.warehouseName like :param0
group by
generatedAlias0.vehicleNo */ select
inwardinve0_.inwardid as inwardid1_13_,
inwardinve0_.created_at as created_2_13_,
inwardinve0_.is_deleted as is_delet3_13_,
inwardinve0_.updated_at as updated_4_13_,
inwardinve0_.additional_info as addition5_13_,
inwardinve0_.date as date6_13_,
inwardinve0_.invoice_received as invoice_7_13_,
inwardinve0_.our_slip_no as our_slip8_13_,
inwardinve0_.contact_id as contact11_13_,
inwardinve0_.supplier_slip_no as supplier9_13_,
inwardinve0_.vehicle_no as vehicle10_13_,
inwardinve0_.warehouse_id as warehou12_13_
from
inward_inventory inwardinve0_ cross
join
warehouse warehouse1_
where
(
inwardinve0_.is_deleted = 'false'
)
and inwardinve0_.warehouse_id=warehouse1_.warehouse_id
and (
warehouse1_.warehouse_name like ?
)
group by
inwardinve0_.vehicle_no
下面是实体class
@Entity
@Table(name = "inward_inventory")
@Audited
@Where(clause = ReusableFields.SOFT_DELETED_CLAUSE)
public class InwardInventory extends ReusableFields implements Cloneable
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="inwardid")
Long inwardid;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd")
@Column(nullable = false)
@NonNull
Date date;
@NonNull
String vehicleNo;
String supplierSlipNo;
String ourSlipNo;
@ManyToMany(fetch=FetchType.EAGER,cascade = CascadeType.ALL)
@JoinTable(name = "inwardinventory_entry", joinColumns = {
@JoinColumn(name = "inwardid", referencedColumnName = "inwardid") }, inverseJoinColumns = {
@JoinColumn(name = "entryId", referencedColumnName = "entryId") })
Set<InwardOutwardList> inwardOutwardList = new HashSet<>();;
@ManyToOne(fetch=FetchType.LAZY,cascade = CascadeType.ALL)
@JoinColumn(name="warehouse_id",nullable=false)
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
Warehouse warehouse;
@ManyToOne(fetch=FetchType.LAZY,cascade = CascadeType.ALL)
@JoinColumn(name="contactId",nullable=false)
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
Supplier supplier;
String additionalInfo;
@NonNull
@Column(nullable = false)
Boolean invoiceReceived;
//getter/setter
}
经过几天的努力终于知道这是一个已知问题
https://jira.spring.io/browse/DATAJPA-1532
因此,我通过自动装配实体管理器处理它,然后创建所有必需的谓词和查询。然后调用 getResults() 而不是 findall()
@Autowired
EntityManager entityManager;
public List<Model> getResults() throws ParseException
{
CriteriaQuery<Model> query = modelSpecification.getSpecQuery();
List<Model> allData = entityManager.createQuery(query).getResultList();
return allData;
}