turbofood
turbofood

Reputation: 312

JPA/Hibernate How to add duplicate values to a List<> with a @OneToMany mapping

I am getting an error every time I try to add duplicate products to the Client class.

org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "uk_8opk6otadh2pkvi9bghguwp89"
  Detail: Key (products_id)=(500010) already exists.

My entities

@Entity
public class Client {
    @Id
    private String id;

    @OneToMany
    private List<Product> products;
}

@Entity
public class Product {
    @Id
    private String id;

    private Boolean foreign;
    private Integer price;
}

When I call .save() hibernate is trying to re-save an already existing Product. I believe this is due to the how it cascades things.

public Client addNewProduct(Client client, Product newProduct) {
    List<Product> products = client.getProducts();
    products.add(newProduct);
    client.setProducts(products);
    return clientRepository.save(client);
}

I just want to be able to add duplicates to a List<>. I believe this is & should be a uni-directional relationship.

Upvotes: 0

Views: 936

Answers (2)

Renis1235
Renis1235

Reputation: 4690

That has nothing to do with JPA or Hibernate. A constraint is a Database constraint and it is right. If a Foreign Key is already part of the table, trying to add it again, violates this constraint. An ID is unique and it should stay that way. So adding duplicates (at least with the same ID) will not work.

Upvotes: 0

PaulD
PaulD

Reputation: 499

This does not work with your current relationship, I don't understand why you would want to add duplicates, but if you have to, then you'd have to create a new entity for that. One example would be something like this:

@Entity
public class ProductBatch {

  @Id
  private String id;

  @OneToOne
  private Product product;

  private Integer count;

  // getter & setter
}

and then you change your Client like this:

@Entity
public class Client {

    @Id
    private String id;

    @OneToMany
    private List<ProductBatch> products;
}

this makes something like this possible for your addNewProduct function:

public Client addNewProduct(Client client, Product newProduct) {
    List<ProductBatch> products = client.getProducts();
    boolean exists = false;
    for(ProductBatch product : products) {
        if(product.getProduct().equals(newProduct)) {
            product.setCount(product.getCount() + 1);
            exists = true;
        }
    }
    if(!exists) {
        BatchProduct product = new BatchProduct();
        product.setProduct(newProduct);
        product.setCount(0);
        products.add(product);
    }
    client.setProducts(products);
    return clientRepository.save(client);
}

Upvotes: 1

Related Questions