Remove many-to-many relationships using criteria in JPA 2.1

I am using EclipseLink 2.5.1 (and Hibernate 4.3.5 final) with JPA 2.1. Given the following tables in MySQL.

  • product
  • prod_colour (connection table)
  • Colour

There is a many-to-many relationship between products and their colors.

A product can have many colors and color, in turn, can be associated with many products. This relationship is expressed in the database by these tables.

The table prod_colourhas two columns of reference prod_idand colour_idof the relevant parent tables productand colourrespectively.

As is obvious, the entity class producthas a list of colors - java.util.List<Colour>which is called colourList.

The entity class colourhas a list of products - java.util.List<Product>called productList.


Communication in the object 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/helper 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);
    }
}

Communication in the object 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.
}

One row from the join table prod_colourcan be deleted row by row:

public boolean delete(Colour colour, Product product)
{
    Colour c=entityManager.find(Colour.class, colour.getColourId());
    Product p=entityManager.find(Product.class, product.getProdId());
    c.removeFromProduct(p);
    return true;
}

Is it possible to get an equivalent query CriteriaDeleteto perform the same operation?

A query similar to the following

CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaDelete<Entity> criteriaDelete = criteriaBuilder.createCriteriaDelete(Entity.class);
Root<Entity> root = criteriaDelete.from(entityManager.getMetamodel().entity(Entity.class));
criteriaDelete.where(criteriaBuilder.equal(root, entity));
entityManager.createQuery(criteriaDelete).executeUpdate();

cannot be written intuitively because there is no entity class for the prod_colourjoin table for which this query must be executed.

Does JPA 2.1 provide something similar for building these kinds of queries?

+4
source share

Source: https://habr.com/ru/post/1543158/


All Articles