5

I'm using EclipseLink 2.5.1 (and Hibernate 4.3.5 final) having JPA 2.1. Given the following tables in MySQL.

  • product
  • prod_colour (join table)
  • colour

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

A product can have many colours and a colour can in turn be associated with many products. This relationship is expressed in the database by these tables.

The prod_colour table has two reference columns prod_id and colour_id from its related parent tables product and colour respectively.

As obvious, the entity class Product has a list of colours - java.util.List<Colour> which is named colourList.

The entity class Colour has a list of products - java.util.List<Product> which is named productList.


The relationship in the Colour entity :

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

The relationship in the Product entity :

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.
}

A single row from the prod_colour join table can be deleted something along the lines :

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;
}

Can we have an equivalent CriteriaDelete query to perform the same operation?

A query like 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 intuitively be written because there is no entity class for the prod_colour join table which this query is to be executed on.

Does JPA 2.1 allow something similar to construct this kind of queries?

Tiny
  • 27,221
  • 105
  • 339
  • 599
  • Do you recall if you ever figured this out? – SnoringFrog Aug 17 '17 at 00:03
  • I stuck on `List#remove()` and avoided bulk delete using `CriteriaDelete` which is part of JPA 2.1. I do not know, if there exists a way to answer this question. – Tiny Aug 18 '17 at 15:33

0 Answers0