JPA - @Feld Version nicht hochgezählt
Ich bin neu in JPA und Hibernate und ich habe ein problem mit der optimistischen sperren. Ich habe eine Klasse, welche ein hase @Version annotiertes Feld. Wenn ich ein update der Entität, repräsentiert durch diese Klasse, die version counter nicht erhöht. Hier ist mein code:
Die Klasse:
@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;
}
und hier ist der main-Methode:
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();
}
}
und hier ist das, was die Konsole sagt:
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=?
Kann jemand mir sagen, was ist falsch?
Edit:
ok, ich habe versucht etwas. Ich habe den sperren, LockModeType.OPTIMISTIC_FORCE_INCREMENT und bekam diese Fehler-Meldung:
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 scheint es klar, dass ich eine nicht-versionierte Entität. Aber warum? Ich hab die @Version-Annotation in meiner Klasse.
Edit:
Ich beginne zu glauben, dass das problem in der persistence.xml. Hier ist es:
<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>
Ist dort irgendetwas falsch?
- Vielleicht haben Sie importiert die falsche
@Version
(aus einer anderen Bibliothek)? - Nein, es ist von javax.Persistenz-Paket, wie alle anderen Kommentare auch.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als ich erklärte, in dieser Artikel, Die
entityManager.persist()
Methode sollte verwendet werden, nur für neue Elemente, die noch nie gespeichert worden ist, bevor.Weil Sie abholen ein Unternehmen, Sie brauchen nicht zu nennen, beibehalten oder Zusammenführen sowieso. Die dirty-checking wird das update auf Ihren Namen.
Der commit-trigger der flush eh so sollten Sie das update angezeigt.
Stellen Sie sicher, dass Sie die
javax.persistence.Version
annotation und nicht aus anderen-Paket (spring data oder so ähnlich).JPA nur updates die version nur, wenn es wirklich existiert, einige schmutzige Daten (uncommitted) präsentieren in der Einheit. Ich nehme an Student 195948 hatte schon semester-Wert als "1". Wenn Sie den Wert, der gleich dem vorherigen Wert, im Idealfall gibt es keine änderung in der Entität Staat. Also der PPV ist nicht die Aktualisierung der version Wert. Wenn Sie die semester-Wert zum anderen Wert (nicht früher), dann gibt es eine änderung im Status der Entität, und es aktualisiert die version-Spalte entsprechend.
Dank,
Jagan
WHERE matnr = ? AND VERSION = theOldVersion
. Ohne die extra-Zustand gibt es keine optimistische sperren geht.Es ist vielleicht nicht genau zum Thema (wie ich es bin mit SpringData repositories), aber wenn ich war auf der Suche nach der Antwort auf mein problem, das ich hier gelandet, so kann dies helfen, die nächste person.
Folgendes ein, und meine version war das Feld nicht zurückgegeben werden aktualisiert.
Am Ende war meine Lösung
Ich vielleicht einen wichtigen Punkt zu Ihrem Problem.
Versuchen Sie, Sie zu ersetzen
zu
Für den Grund, dass die @Version-Tags können nicht mit primitiven Typ.Danke.