简体   繁体   中英

Why does Hibernate entity manager perform insert instead of update when dettached entity version property is null?

I've noticed that when you have an entity with a @Version property and you try to update a record by manually instantiating the entity, setting its id to an existing id and calling merge(), Hibernate performs an insert instead of an update. I assume this is because the version property is null on the manually instantiated object. Isn't the existence of the identifier adequate for Hibernate to determine that it should perform an update?

Example code:

Assume there is a record with id=1 in the database and MyEntity has a property version with @Version.

MyEntity e = new MyEntity();
e.setId(1);
e.setName("some updated value");

entityManager.merge(e);

This ends up performing an insert instead of an update.

MyEntity is something like:

@Entity
public class MyEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Integer id;

    @Column("name")
    String name;

    @Version
    Integer version;

}

If I remove the @Version, it works as expected, the record with id=1 is updated.

The documentation confirms your experience:

A version or timestamp property should never be null for a detached instance. Hibernate will detect any instance with a null version or timestamp as transient, irrespective of what other unsaved-value strategies are specified.

Even if it used the ID to determine if the entity is detached or not, trying to merge an entity with a null version would lead to an optimistic lock exception anyway. You simply shouldn't merge detached objects with null versions. That defeats the purpose of using optimistic locking.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM