JPA @Version field does not increase

I am new to JPA and Hibernate, and I have a problem with optimistic locking. I have a class that has an @Version annotated field in it. When I update the Entity represented by this class, the version counter does not increment. Here is my code: Class:

@Entity @Table (name = "Studenten") public class Student implements Serializable{ private static final long serialVersionUID = 705252921575133272L; @Version private int version; private int matrnr; private String name; private int semester; public Student (){ } public Student (int matrnr, String name){ this.matrnr = matrnr; this.name = name; } public Student (int matrnr, String name, int semester){ this(matrnr, name); this.semester = semester; } 

and here is the main method:

 public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("VEDA_Vortrag"); EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); try{ tx.begin(); Student s = em.find(Student.class, 195948); s.setSemester(1); em.persist(s); tx.commit(); }catch(Exception e){ if(tx != null && tx.isActive()){ tx.rollback(); System.out.println("Error in Transaction. Rollback!"); } } finally{ em.close(); emf.close(); } } 

and here is what the console says:

 Hibernate: select student0_.matrnr as matrnr0_0_, student0_.name as name0_0_, student0_.semester as semester0_0_, student0_.version as version0_0_ from Studenten student0_ where student0_.matrnr=? Hibernate: update Studenten set name=?, semester=?, version=? where matrnr=? 

Can someone tell me what is wrong?

Edit: ok, i tried something. I set the lock on LockModeType.OPTIMISTIC_FORCE_INCREMENT and received this error message:

 ERROR: HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: cannot force version increment on non-versioned entity Jun 20, 2014 9:00:52 AM org.hibernate.AssertionFailure <init> 

So it seems clear that I have an object without a version. But why? I have an @Version annotation in my class.

Edit: I am starting to think that the problem is persistence.xml. Here he is:

 <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0"> <persistence-unit name="VEDA_Vortrag"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/uni"/> <property name="javax.persistence.jdbc.user" value="*******"/> <property name="javax.persistence.jdbc.password" value="******"/> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.format_sql" value="true"/> </properties> </persistence-unit> 

Is there something wrong?

+7
java mysql hibernate jpa transactions
source share
4 answers

As I explained in this article , the entityManager.persist() method is intended to be used only for new objects that have never been saved before.

Since you are choosing an entity, you do not need to call persist or merge in any case. a dirty check will update on your behalf.

In either case, the commit will trigger a flash, so you should see an update.

Make sure you use the javax.persistence.Version annotation and not from another package (spring data or something similar).

+7
source share

JPA only updates the version only when in fact there is some kind of dirty data (uncommitted) present in the entity. I assume Student 195948 already had a semester value of "1". Although you set the value equal to the previous value, ideally there is no change in the state of the object. Therefore, JPA does not update the version value. If you set the semester value to a different value (and not to an earlier one), the state of the object changes and the version column is updated accordingly.

Thanks Jagana

+1
source share

I can find an important point in your problem. Try replacing

 private int version 

in

 private Long version 

For the reason that the @Version tag may not work with a primitive type. Thanks.

0
source share

It may not be entirely off topic (since I use SpringData repositories), but when I looked for the answer to my problem, I ended up here, so this can help the next person.

the following and my version field did not return updated.

 savedJpa = repository.save(updateJpa); 

In the end, my decision was

 savedJpa = repository.saveAndFlush(updateJpa); 
0
source share

All Articles