我正在使用Spring框架。我有两张桌子套餐&项目和关系是一个包有很多项目。表格设计类似于:
@Entity
@Table(name = "TB_PACKAGE")
public class Packages implements Serializable{
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(name = "PACKAGE_ID")
private String packageId;
@Valid
@OneToMany(mappedBy = "packages", cascade = { CascadeType.ALL })
private List<Item> item;
@Entity
@Table(name = "TB_ITEM")
public class Item implements Serializable{
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(name = "ITEM_ID")
private String itemId;
@ManyToOne
@JoinColumn(name="PACKAGE_ID")
private Packages packages;
@Transient
private String packageId;
这是我通过使用CriteriaBuilder来获取连接表的代码来获得这样的结果。
SELECT * FROM Packages p JOIN Item i ON p.packageId = i.packageId;
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Packages> cq = cb.createQuery(Packages.class);
Root<Packages> pRoot = cq.from(Packages.class);
Join<Packages, Item> packagesItem = pRoot.join("item");
List<Predicate> predicates = new ArrayList<Predicate>();
if (StringUtils.isNotEmpty(itemName)) {
predicates.add(cb.like(cb.lower(packagesItem.<String>get("itemName")), "%" + itemName.toLowerCase() + "%"));
}
Predicate[] predArray = new Predicate[predicates.size()];
predicates.toArray(predArray);
cq.where(predArray);
cq.distinct(true);
TypedQuery<Packages> query = em.createQuery(cq);
return query.getResultList();
如果我输入'phone'作为我的参数,它假设应该记录为JSON:
"packageId": "P1",
"item": [
{
"itemId": "Item 1",
"temName" "Phone"
}
]
然而,这些包总是加载它的所有孩子:
"packageId": "P1",
"item": [
{
"itemId": "Item 1",
"temName" "Phone"
},
{
"itemId": "Item 2",
"temName" "Laptop"
},
{
"itemId": "Item 3",
"temName" "Mouse"
}
]
我已经尝试了一切:FetchType.Lazy,QueryDsl,Native Query,HQL等但仍然没有运气。有人有解决方案吗?
答案 0 :(得分:0)
您的@OneToMany
映射似乎不正确。
尝试更改
@Valid
@OneToMany(mappedBy = "items", cascade = { CascadeType.ALL })
private List<Item> item;
到
@Valid
@OneToMany(mappedBy = "packages", cascade = { CascadeType.ALL })
private List<Item> item;
完成映射后,您必须检查JOIN FETCH
答案 1 :(得分:0)
我认为问题出在JOIN
上的SQL语法上。
INNER JOIN:当BOTH表中至少有一个匹配时返回所有行
LEFT JOIN:返回左表中的所有行,以及右表中匹配的行
有时它被称为
LEFT OUTER JOIN
。RIGHT JOIN:返回右表中的所有行,以及左表中匹配的行
FULL JOIN:当其中一个表中存在匹配时返回所有行
使用JOIN
时,默认情况下,至少对于SQL Server和MySQL,与INNER JOIN
等效。我认为您的底层lib / jar还将为您提供其他JOIN
类型的类。
尝试指定INNER JOIN
,或尝试WHERE
。对我来说WHERE
更清楚。
这个问题可能有所帮助:
答案 2 :(得分:0)
您需要的是JOIN FETCH而不是JOIN
Join<Packages, Item> packagesItem = pRoot.fetch("item");
作为JPQL
Select packages from Packages packages join fetch packages.item where packages.item.temName like '%'+itemName+'%';
how-to-properly-express-jpql-join-fetch-with-where-clause-as-jpa-2-criteriaq