Reputation: 9400
I have an entity similar to:
@Entity
@Table( name="marchi", uniqueConstraints=@UniqueConstraint(columnNames="codice") )
public class Marchio implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
private String codice;
private String nome;
//...
}
I create a Marchio with codice = 123, then I persist it. OK!
Then I retrieve it from the DB via a query, edit the "nome" property with something and call merge(). OK!
Then I create another Marchio with codice = 123. I put something in nome and call merge().
Result is:
ConstraintViolationException: Duplicate entry '123' for key 'codice'
Good, actually I can use the first way: query, edit property nome and merge.
Consider I don't have only "nome". I have 35 different properties, so I don't want to:
Marchio m = em.findCodice("123");
m.setP1("1");
m.setP2("2");
...
m.setPN("N");
em.merge(m);
How can I do?
Upvotes: 3
Views: 4652
Reputation: 42
The main intention of the merge method is to update a persistent entity instance with new field values from a detached entity instance. Firs of all, we need to get a persistent entity instance from a persistence context and update its fields with new values from this detached instance. So the merge method does exactly that: finds an entity instance by id taken from the passed object (either an existing entity instance from the persistence context is retrieved, or a new instance loaded from the database) copies fields from the passed object to this instance returns a newly updated instance. When you do that: "Then I create another Marchio with codice = 123" you create a new Marchio in transient state (without id). New Marchio it`s diferent Marchio then in database. For new Marchio in transient state operation MERGE do sql insert. For old Marchio in persistent state operation MERGE do sql update. For Insert you have a unique constraint. Here is the exception from the database. First of all, get the Marchio from the base ( find() or getReference() ). Then change the fields in it(Persistent Marchio) and then call MERGE. All this should be one unit of work (one transaction).
Upvotes: 0
Reputation: 4211
If I've understood well, you already have a detached object with updated values and you don't want to retrieve the corresponding object from the db and update it calling many set methods. The only way to accomplish this is to remove the old object and then persist the detached new object:
em.remove(oldobj);
em.persist(newobj);
Upvotes: 3
Reputation: 2408
Try this:
@Table(name = "marchi", uniqueConstraints={@UniqueConstraint(columnNames="codice"), @UniqueConstraint(columnNames="nome")})
I believe with the above you can have:
codice nome
123 A
123 B
123 C
Upvotes: -1