Hibernate EntityManager.merge () causes a new object to be created instead of updating an existing one

I have the following (partial) hierarchy:

 @MappedSuperclass public abstract class PersistentEntity { @Id @GeneratedValue(generator="system-uuid") @Type(type = "pg-uuid") public UUID getId() { return id; } } 

@Entity @Inheritance (strategy = InheritanceType.JOINED) @DiscriminatorColumn (name = "TYPE", discriminatorType = DiscriminatorType.STRING) public abstract class AbstractCredential extends PersistentEntity {// content}

@Entity @DiscriminatorValue ("Standard") @PrimaryKeyJoinColumn (name = "ID") public class StandardCredential extends AbstractCredential {// hashcode and quals here, by full data}

AbstractCredential is an object instead of @MappedSuperclass, so I can select it from id and get the corresponding "specific" class. my problem is that if I create a new (separate) instance with the identifier of an existing instance and then pass this separate instance to merge, hibernate creates a new object (which means that it generates a new identifier and overrides the id field in my newly created instance ) in my understanding, hibernate had to override all fields in an existing instance with values ​​in a separate instance.

what am I doing wrong?

+4
source share
1 answer

It may be wrong, but I think that separate and new are two different states in the life cycle of entities. A single object was loaded from the database in the session, but the session was closed. However, in this case, Hibernate should know that the object already exists in the database and updates the values ​​accordingly when the object is subsequently merged. The same thing will not happen with objects created using the new keyword, even if @Id is equal.

This diagram clearly shows that an object in the New / Transient state is different from Detached (JPA). Here Hibernate (3.5) is manual input for entity states. I also tested using Persistence Java Persistence with JPA and Spring with Hibernate to explain how entity states and transitions are the same (a separate object must be saved / retrieved from the database and then removed from the persistence context / session to disconnect). Unfortunately, I could not find any mention of how the merge should work when you create a new object through new and assign it an identifier manually, which makes me think that the merge should not be used that way. However, it may be wrong.

+4
source

Source: https://habr.com/ru/post/1340515/


All Articles