JPA Error: detached entity passed to persist when attempting to persist multiple duplicated instances

Viewed 73

I've got two OneToMany relations between an entity and two lists of objects and one ManyToOne relation between the same entity and another entity as better explained below:

  1. Entity VehicleRent has one or many Car (a list of Car) and one or many Bike (a list of Bike);
  2. Entities VehicleRent belong to one User.

When persisting (em.persist()) VehicleRent for the first time, it all goes well. However, when I try to persist a new, but different VehicleRent afterwards it keeps overwriting the first one.

Also, when I try to duplicate an existing instance of VehicleRent it returns the following error:

select
        nextval('rent_seq')
jakarta.persistence.PersistenceException: Converting `org.hibernate.PersistentObjectException` to JPA `PersistenceException` : detached entity passed to persist: poo.models.User

I am using the GenerationType.SEQUENCE for generating all classes' ids with each one having its specific SequenceGenerator (i.e. rent_seq for VehicleRent, car_seq for Car etc.).

In all relations, I am also using CascadeType.ALL.

Basically, I would like to persist as many VehicleRent instances as I would like to, regardless of them having duplicate or different attributes.

How can I achieve this behavior? I would really appreciate any help.

Edit 1: Renting method from User.java

public void Renting(List<Car> Carlist, List<Bike> Bikelist, User user) {
    VehicleRent rent = new VehicleRent(Carlist, Bikelist, user);

    EntityManagerFactory emf = Persistence.createEntityManagerFactory("default");
    EntityManager em = emf.createEntityManager();

    try{
        em.getTransaction().begin();
        em.persist(rent);
        em.getTransaction().commit();
    } catch (Exception e) {
        e.printStackTrace();
    }

    em.close();
    emf.close();
}

Edit 2: Entities (getters and setters ignored)

User

@Entity
@SequenceGenerator(name = "user_seq", sequenceName = "user_seq", allocationSize = 1, initialValue = 1)
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_seq")
    private long id;
    private String firstName;
    private String lastName;
    private String nickName;
    private String password;
    private String mail;

    public User() {
    }

VehicleRent

@Entity
@SequenceGenerator(name = "rent_seq", sequenceName = "rent_seq", allocationSize = 1, initialValue = 1)
public class VehicleRent{
   @Id
   @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "rent_seq")
   private long id;

   @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, targetEntity = Car.class)
   @JoinColumn(name = "rent_id")
   private List<Car> Carlist;

   @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, targetEntity = Bike.class)
   @JoinColumn(name = "rent_id")
   private List<Bike> Bikelist;

   @ManyToOne(cascade = CascadeType.ALL) 
   @JoinColumn(name = "user_id")
   private User tenant;

public VehicleRent(List<Car> Carlist, List<Bike> Bikelist, User tenant){ 
      this();
      this.Carlist = Carlist ;
      this.Bikelist= Bikelist;
      this.tenant = tenant;
   }

   public VehicleRent() {
   }

Bike

@Entity
@SequenceGenerator(name = "bike_seq", sequenceName = "bike_seq", allocationSize = 1, initialValue = 1)
public class Bike extends Vehicle{
    
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "bike_seq")
    private long id; // I can't keep id into parent Vehicle because they'll both share the same generator (each must have their own for proper persistence).

    private int cc;
    private String type;

    public Bike() {
    }

Car

@Entity
@SequenceGenerator(name = "car_seq", sequenceName = "car_seq", allocationSize = 1, initialValue = 1)
public class Car extends Vehicle {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "car_seq")
private long id; // I can't keep id into parent Vehicle because they'll both share the same generator (each must have their own for proper persistence).

private String paint;
private boolean twoDoors;

public Car() {
}
1 Answers

Something is wrong with sequences probably.

Please try this:

  1. DROP sequence rent_seq in database
  2. Run the version below:
@Entity
public class VehicleRent{
   @Id
   @GeneratedValue(strategy=GenerationType.AUTO)
   private long id;

If you get errors with other entities (Car / car_seq), do the same for them.

It works for sure in DataNucleus and H2. DBMS should create and manage sequences by itself.

Related