hibernate - 防止 JPA 中多对多关系的联接表中出现重复条目

标签 hibernate jpa many-to-many eclipselink jpa-2.1

我正在使用 EclipseLink 2.5.1(和 Hibernate 4.3.5 Final)。给出 MySQL 中的下表。

  • 产品
  • prod_colour(连接表)
  • 颜色

产品及其颜色之间存在多对多关系。

一个产品可以有多种颜色,而一种颜色又可以与许多产品相关联。这种关系在数据库中通过这些表来表达。

prod_colour表有两个引用列 prod_idcolour_id来自其相关父表 productcolour分别。

很明显,实体类 Product有一个颜色列表 - java.util.List<Colour>其名称为colourList .

实体类Colour有产品列表 - java.util.List<Product>其名称为productList .

<小时/>

Colour中的关系实体:

public class Colour implements Serializable {

    @JoinTable(name = "prod_colour", joinColumns = {
        @JoinColumn(name = "colour_id", referencedColumnName = "prod_id")}, inverseJoinColumns = {
        @JoinColumn(name = "prod_id", referencedColumnName = "colour_id")})
    @ManyToMany(mappedBy = "colourList", fetch = FetchType.LAZY)
    private List<Product> productList; //Getter and setter.

    //---Utility methods---

    //Add rows to the prod_colour table.
    public void addToProduct(Product product) {
        this.getProductList().add(product);
        product.getColourList().add(this);
    }

    //Delete rows from the prod_colour table.
    public void removeFromProduct(Product product) {
        this.getProductList().remove(product);
        product.getColourList().remove(this);
    }
}

Product中的关系实体:

public class Product implements Serializable {

    @JoinTable(name = "prod_colour", joinColumns = {
        @JoinColumn(name = "prod_id", referencedColumnName = "prod_id")}, inverseJoinColumns = {
        @JoinColumn(name = "colour_id", referencedColumnName = "colour_id")})
    @ManyToMany(fetch = FetchType.LAZY)
    private List<Colour> colourList; //Getter and setter.
}

从关联的 EJB 中,执行插入操作如下。

@Override
@SuppressWarnings("unchecked")
public boolean insert(List<Colour> colours, Product product)
{
    int i=0;
    Long prodId=product.getProdId();
    for(Colour colour:colours)
    {
        Product p = entityManager.getReference(Product.class, prodId);
        colour.addToProduct(p);

        if(++i%49==0)
        {
            entityManager.flush();
        }
        entityManager.merge(colour);
        entityManager.merge(p);
    }
    return true;
}

一切正常。

<小时/>

当尝试重复行时(与相同 Colour 实体关联的相同 Product 实体),它们也会被插入到 prod_colour 中我预计不会发生的表。

我是否需要执行一些额外的条件检查以避免重复插入,或者 EclipseLink/Hibernate 有某种机制来防止在这种情况下重复插入?

最佳答案

这也让我感到惊讶。我一直认为它将连接表中的引用列作为复合主键,但事实并非如此。如果您想要拥有唯一的记录,请尝试使用 Set 而不是 List 或使用复合主键(color_id、product_id)创建您自己的多对多关系表。我没有更好的主意。

关于hibernate - 防止 JPA 中多对多关系的联接表中出现重复条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23340004/

相关文章:

orm - 我如何在 schema.yml Doctrine symfony 1.4 中进行排序

php - 如何在并排列上查看多对多表

java - 使用 map 集合 hibernate 多对多

eclipse - 注销 JDBC 驱动程序?

java - Spring Boot OneToOne保存(): A different object with the same identifier value was already associated with the session

java - 使用 Hibernate Annotation 更新现有实体类的列名称

java - EclipseLink 期望在堆栈上找到对象/数组

java - 如何在 Hibernate 中形成这个复杂的查询?

java - Hibernate一对多关系java.sql.SQLIntegrityConstraintViolationException : Column 'person_id' cannot be null

java - 构建 CriteriaBuilder 查询来比较列表