Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating hibernate version manually

I have two classes say Foo and Bar mapped as @OneToOne (bidirectional) using Hibernate (3.6.1 final) with JPA (2.0) like -

@Entity
public class Foo{
    @Id
    private Long id;

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "foo")
    private Bar bar;

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "foo")
    private Qux qux;

    @Version
    private int version;

    // getters and setters omitted
}

@Entity
public class Bar{
    @Id
    private Long id;

    @OneToOne
        @JoinColumn(name = "foo_id",  nullable = false)
    private Foo foo;

    // getters and setters omitted
}

@Entity
public class Qux {
    @Id
    private Long id;

    @OneToOne
        @JoinColumn(name = "foo_id",  nullable = false)
    private Foo foo;

    // getters and setters omitted
}

Note that - Bar and Qux doesn't have @Version column

If we update Bar then hibernate will not increment the version of Foo and same for Qux. But our business logic needs - if someone updates Bar in the Foo and other thread is trying to update the Qux of the same Foo but doesn't have updated Bar and vice versa then such updates should fail.
Since hibernate doesn't update the version property of Foo if we update the Bar, we decided to update the version of Foo manually (I know it's pretty weird and not recommended) if we update the Bar and Qux.
It works perfectly fine.. but I'm worry about some corner cases in concurrency which may fail this or will have unintended behavior.
Is it safe to do this kind of tweak with version for this purpose? OR is there any other better alternative to this (I've already tried optimistic/pessimistic force increament)

like image 369
Premraj Avatar asked Mar 14 '11 13:03

Premraj


People also ask

How do I know what version of Hibernate I have?

Check if your Hibernate JAR has a META-INF/MANIFEST. MF with the version in it. It looks like the JBoss folks were using Ant at this time and the Manifest doesn't provide the version. Dig the JBoss Embedded SVN to find out what they're doing exactly.

How does version checking works in hibernate?

If the data is read by two threads at the same time, and both try to update the same row with different values, Hibernate uses the @Version field to check if the row is already updated. Before committing, each transaction verifies that no other transaction has modified its data.

How do you update an object in hibernate?

We can update an object in hibernate by calling the update() method, provided by the org. hibernate. Session. Though the update() method is used to update an object, there are two different ways to use update() method.

How to update an object in hibernate?

We can update an object in hibernate by calling the update () method, provided by the org.hibernate.Session. Though the update () method is used to update an object, there are two different ways to use update () method. Without loading an object from the database Loading an object from the database

How do I force a version change in a hibernate entity?

Hibernate generates an UPDATE statement that only increments the version while leaving all the other columns unchanged (their values are identical to the ones that were previously loaded from the database): If you want to force an entity version change, you need to use either OPTIMISTIC_FORCE_INCREMENT or PESSIMISTIC_FORCE_INCREMENT.

What does the @version annotation do in hibernate?

The @Version annotation allows Hibernate to activate the optimistic locking mechanism whenever executing an UPDATE or a DELETE statement against the entity in question.

What is the latest version of hibernate search?

This is an upgraded version of Hibernate ORM 5.2 and Hibernate Search 5.9. Compatible with Java 8 and the latest version, JPA 2.1 and Hibernate ORM 5.2, Hibernate search 5.9. Hibernate OGM is also compatible with this version.


1 Answers

The correct way to force version update is the following:

em.lock(entity, LockModeType.OPTIMISTIC_FORCE_INCREMENT);

It's intended to be used in such cases.

Other methods of EntityManager that take LockModeType can be used as well.

like image 152
axtavt Avatar answered Oct 03 '22 06:10

axtavt