我正在使用 JPA 运行 NativeQuery,与在 sql 工具中运行查询相比,它给出了不同的结果。可能我误会了…… 在@SQLResultSetMapping 的概念内。
- - 概述 - -
我将结果映射到两个实体,所以我希望收到一个实体对列表。这行得通。
当你看下面的图片时,你会在一个 sql 工具中看到查询的结果,其中 ..
- .. RED BOX 映射到一个实体
- .. 绿框映射到第二个实体
JPA 应该给我一个本地行作为一对两个实体。
问题
这就是事情出错的地方。是的,我将收到两个实体对的列表,但与图片不同的是,“pp.id”列不会遍历相应表的所有行(在图片“5,6,7,..”中,来自 JPA “5,5,5,5,..”)。
pp.id 列是一个连接列,我想当涉及到 Joins + SQLResultSetMappings 时,我误解了 JPA 中的一些内容。在我看来,不同之处在于 JPA 总是从表“propertyprofile”中加入同一行(下面有更多详细信息),这与在 sql 中运行查询不同。
我希望有人同情我并帮助我。:)
- - 细节 - -
询问
我基本上是想找出是否每个“产品”都为预定义的“属性”(表属性配置文件)定义了一个“值”(表属性值)。
可能最相关的部分在底部,其中“propertyprofile”被连接,“propertyvalue”被左连接。
select sg.ID as 'sg.id', sg.Name as 'sg.name', ppcount.totalppcount as 'sg.totalppcount', ppcount.totalppothercount as 'sg.totalppothercount',
p.ID as 'product.id', pp.id as 'pp.id', pp.Role as 'pp.role', pp.Name as 'pp.name',
(case when pv.id is null then '0' else '1' end) as 'hasPropertyValue', pv.ID as 'pv.id', pv.StringValue, pv.IntervallMin, pv.IntervallMax
from shoppingguide sg
join
(
select sg.ID as 'sgid', count(*) as 'totalppcount', count(pp_other.ID) as 'totalppothercount' from propertyprofile pp_all
left join propertyprofile pp_other on pp_other.id = pp_all.id AND pp_other.Role = '0'
join shoppingguide sg on pp_all.ShoppingGuideID = sg.ID
join shopifyshop ss on sg.ShopifyShopID = ss.ID
where
pp_all.ShoppingGuideID = sg.ID AND
ss.Name = :shopName
GROUP BY pp_all.ShoppingGuideID
) ppcount on ppcount.sgid = sg.id
join shopifyshop ss on sg.ShopifyShopID=ss.ID
join product p on p.ShopifyShopID = ss.ID
join propertyprofile pp on (pp.ShoppingGuideID = sg.id AND pp.Role = '0')
left join propertyvalue pv on (pv.ProductID=p.ID and pv.PropertyProfileID = pp.id)
where
ss.Name = :shopName
order by sg.id asc, p.id asc, pp.id asc
;
表
涉及到很多表,但这些是理解查询最重要的表:
- 产品
- propertyprofile - 所有产品都具有的特征(例如高度、价格)
- propertyvalue - 特定特征的数据;与财产概况有关(例如 5 厘米;120 美元)
SQLResultSetMapping
映射在两个实体上完成:ProductDataFillSummary_ShoppingGuideInformation、ProductDataFillSummary_ProductInformation。
@SqlResultSetMapping(
name = "ProductDataFillSummaryMapping",
entities = {
@EntityResult (
entityClass = ProductDataFillSummary_ShoppingGuideInformation.class,
fields = {
@FieldResult(name = "shoppingGuideId", column = "sg.id"),
@FieldResult(name = "shoppingGuideName", column = "sg.name"),
@FieldResult(name = "numberOfTotalPropertyProfiles", column = "sg.totalppcount"),
@FieldResult(name = "numberOfTotalPropertyProfilesOther", column = "sg.totalppothercount")
}),
@EntityResult(
entityClass = ProductDataFillSummary_ProductInformation.class,
fields = {
@FieldResult(name = "productID", column = "product.id"),
@FieldResult(name = "propertyProfileId", column = "pp.id"),
@FieldResult(name = "propertyProfileRole", column = "pp.role"),
@FieldResult(name = "propertyValueId", column = "pv.id"),
@FieldResult(name = "hasPropertyValue", column = "hasPropertyValue")
}
)
})