I'm using EclipseLink 2.5.1 (and Hibernate 4.3.5 final). 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 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.
}
From the associated EJB, the insert operation is performed as follows.
@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;
}
Everything works fine.
When duplicate rows are attempted (same Colour
entities associated with the same Product
entity), they are also inserted into the prod_colour
table that I expect should not happen.
Do I need to perform some extra conditional checks to avoid duplicate insertion or EclipseLink/Hibernate have some mechanism to prevent duplicates in such situations?