JPA一个一对多的连接表给出不正确的子记录(JPA One-To-Many join table g

2019-09-28 13:34发布

我使用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得到结果像这样连接表。

SQL:

    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();

如果我输入“手机”作为我的参数,它想应该拿出一个记录作为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,原生查询,HQL等,但仍然没有运气。 任何人有解决办法吗?

Answer 1:

我认为这个问题是在SQL语法,上JOIN

INNER JOIN:返回所有行时,有两个表中至少有一个匹配

LEFT JOIN:左表返回所有行和右表匹配的行

有时它被称为LEFT OUTER JOIN

RIGHT JOIN:右表中返回所有行和左表匹配的行

FULL JOIN:返回所有行的时候没有在表中的一个匹配

当您使用JOIN ,默认情况下,至少在SQL Server和MySQL,是equivalant到INNER JOIN 。 我想你的潜在的lib /罐也将为您提供类其他JOIN类型。

尝试指定INNER JOIN ,或给WHERE一试。 对我来说, WHERE更清晰。

这个问题可能会有所帮助:

Hibernate的默认加盟为空的许多到一个



Answer 2:

@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



Answer 3:

你需要的是连接抓取,而不是JOIN

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

作为JPQL

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

如何对正确-EXPRESS-JPQL联接取与- where子句-AS-JPA -2- criteriaq



文章来源: JPA One-To-Many join table give incorrect child records