Я использую EclipseLink 2.5.1 (и Hibernate 4.3.5 final). Учитывая следующие таблицы в MySQL.
- товар
- prod_color (присоединить таблицу)
- цвет
Между продуктами и их цветами существует связь «многие ко многим».
Продукт может иметь много цветов, а цвет, в свою очередь, может быть связан со многими продуктами. Эта связь выражается в базе данных этими таблицами.
Таблица prod_colour
имеет два ссылочных столбца prod_id
и colour_id
из связанных родительских таблиц product
и colour
соответственно.
Как очевидно, класс объектов 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 есть какой-то механизм для предотвращения дублирования в таких ситуациях?