JPA一对多联接表给出了不正确的子记录 [英] JPA One-To-Many join table give incorrect child records

查看:116
本文介绍了JPA一对多联接表给出了不正确的子记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Spring框架.我有两个表Package&项目与关系是一个包中有许多项目.表格设计类似于:

I'm using Spring framework. I have two tables Package & Item and the relationship is one Package has many Items. The tables design is something like:

    @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来获得类似结果的方式来编写代码以连接表的方式.

This is how I write my code to join table by using CriteriaBuilder to get result like this.

    SELECT * FROM Packages p JOIN Item i ON p.packageId = i.packageId; 

Java:

    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记录形式出现:

If I enter 'phone' as my parameter, it suppose should come out with a record as JSON:

   "packageId": "P1",
   "item": [
        {
          "itemId": "Item 1",
          "temName" "Phone"
        }
    ]

但是,软件包始终像这样加载其所有子对象:

However the packages always load with all its child like this:

   "packageId": "P1",
   "item": [
        {
          "itemId": "Item 1",
          "temName" "Phone"
        },
        {
          "itemId": "Item 2",
          "temName" "Laptop"
        },
        {
          "itemId": "Item 3",
          "temName" "Mouse"
        }
    ]

我已经尝试了所有方法:FetchType.Lazy,QueryDsl,Native Query,HQL等,但还是没有运气.有解决方案的人吗?

I have tried everything: FetchType.Lazy, QueryDsl, Native Query, HQL and etc. but still no luck. Anyone has the solution?

推荐答案

您需要的是JOIN FETCH而不是JOIN

What you need is JOIN FETCH instead of JOIN

Join<Packages, Item> packagesItem = pRoot.fetch("item");

作为JPQL

Select packages from Packages packages join fetch packages.item where packages.item.temName like '%'+itemName+'%';

查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆