2014-06-20 17 views
7

JPA ve Hazırda Bekletme konusunda yeniyim ve iyimser kilitleme ile ilgili bir sorunum var. @Version açıklamalı alanı olan bir sınıfım var. Bu sınıf tarafından temsil edilen Varlığı güncellediğimde, sürüm sayacı artmaz. sınıf : İşte benim kodudurJPA @Version alanı artırılmıyor

@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; 
} 

ve burada ana yöntemdir: Burada

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(); 
    } 
} 

ve konsol diyor:

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=? 

biri olsun bana söyleyebilir yanlış?

Düzeltme: tamam, bir şey denedim. Ben LockModeType.OPTIMISTIC_FORCE_INCREMENT için kilitleme ayarlayabilir ve bu hata-mesajı var:

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> 

Demek ki ben bir sürüm bilgisi olmayan varlık olduğu açık gözüküyor. Ama neden? Sınıfımda @Version Açıklaması var.

Düzenleme: Sorunun persistence.xml dosyasında olduğunu düşünmeye başladım. İşte burada: yanlış bir şey

<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> 

var mı?

+0

Belki de yanlış '@ Version' (başka bir kitaplıktan) aldınız? – Thilo

+0

Hayır, diğer tüm ek açıklamalar da olduğu için javax.persistence paketinden değil. – Raistlin

cevap

7

sadece daha önce kalıcı hiç yeni varlıklar için kullanılacak.

Bir öğeyi getirdiğiniz için, arama yapmak zorunda kalmazsınız veya yine de birleştirme. dirty checking güncellemeyi sizin adınıza yapacak.

Takibi yine de temizlemeyi tetikleyecektir, böylece güncelleştirmeyi görmeniz gerekir.

javax.persistence.Version ek açıklamasını kullandığınızdan emin olun, diğer paketlerden değil (yay verileri veya benzerleri).

+0

Öneriniz için teşekkürler. EntityManager.persist yöntemindeki çağrıyı kaldırdım ancak sorun hala aynı. Ayrıca, Versiyon açıklama notundan gelen paketi de kontrol ettim. Bu javax.persistence paketidir. :( – Raistlin

+0

SQL günlüğü çıktıyı çıkarır, böylece her zaman değiştirir ve birleştirirken bile 0'ı görürsünüz. –

+0

tamam, fakat "studenten'den select *" dediğimde, çıktıdaki yeni Sürüm değerini görmemeliyim? – Raistlin

1

JPA yalnızca sürümü yalnızca kuruluşta var olan bazı kirli verileri (kaydedilmemiş) varsa gerçekten günceller. 195948 numaralı öğrencinin halihazırda yarıyıl değeri "1" olduğunu varsayıyorum. Bir önceki değere eşit olan değeri ayarlıyor olsanız da, ideal olarak varlık durumunda hiçbir değişiklik olmaz. Bu nedenle JPA, sürüm değerini güncelleştirmiyor. Yarıyıl değerini farklı bir değere (daha önce değil) ayarlarsanız, varlık durumunda bir değişiklik olur ve buna göre sürüm sütununu günceller. Ben this article açıklandığı gibi, entityManager.persist() yöntem kastedilmektedir

sayesinde Ramazan

+0

Cevabınız için teşekkürler, ama yaptığım şey buydu;). Dönem değeri 2 idi ve onu 1 olarak güncelledim. – Raistlin

+0

Peki neden bir SQL UPDATE yayımlanıyor? Ve son derece tehlikeli gibi görünen sürüm alanını kontrol etmek bile zahmet etmiyor. – Thilo

+0

Aslında, öğrenci tablosunu alan dönemi için yeni bir değerle güncelliyorum. Bu yüzden sürüm alanını kontrol etmelisiniz.Neden olmadığını bilmiyorum. Bu benim sorunum. – Raistlin