2016-04-16 8 views
0

私の簡単なコードは、XMLファイルにいくつかのコードを保存します。ここでhibernateのupdateメソッドは、古いデータを置き換えるのではなく、新しいデータを作成しますか?

<?xml version='1.0' encoding='utf-8'?> 

    <!-- JDBC connection pool (use the built-in) --> 
    <property name="connection.pool_size">1</property> 

    <!-- SQL dialect --> 
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property> 

    <!-- Disable the second-level cache --> 
    <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> 

    <!-- Echo all executed SQL to stdout --> 
    <property name="show_sql">true</property> 

    <!-- Drop the existing tables and create new one --> 
    <property name="hbm2ddl.auto">update</property> 

    <!-- Mention here all the model classes along with their package name --> 

    <mapping class="com.hibernate.Student"/> 

</session-factory> 

私の学生のクラス、

package com.hibernate; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.Table; 


@Entity 
@Table(name="STUDENT") 
public class Student { 

@Id @GeneratedValue(strategy=GenerationType.AUTO) 
private int rollNo; 

@Column(name="FULL_NAME",nullable=false) 
private String name; 

public int getRollNo() { 
    return rollNo; 
} 
public void setRollNo(int rollNo) { 
    this.rollNo = rollNo; 
} 
public String getName() { 
    return name; 
} 
public void setName(String name) { 
    this.name = name; 
} 
} 

メインです:まず

package com.hibernate; 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.hibernate.cfg.Configuration; 

public class Main { 
    public static void main(String[] args){ 
     Student student= new Student(); 
     student.setName("Chang"); 
     SessionFactory sessionFactory=new Configuration().configure().buildSessionFactory(); 
     Session session=sessionFactory.openSession(); 
     session.beginTransaction(); 

     //session.save(student); 

     //get a student from the databse 
     student=(Student)session.get(Student.class, 1); 
     System.out.println("Student Object have student name as:"+student.getName()); 

     student.setName("Chang_update"); 
     session.update(student); 

     session.getTransaction().commit(); 
     session.close(); 
     //sessionFactory.close();  
    } 
} 

、私は新しいテーブルを作成し、新しい学生を挿入したいです。だから私は<property name="hbm2ddl.auto">create</property>を手放す。そして私は、私は、コードのこれらの部分を持っていないsession.save(student);を持っている:

student=(Student)session.get(Student.class, 1); 
System.out.println("Student Object have student name as:"+student.getName()); 

student.setName("Chang_update"); 
session.update(student); 

それから私は、getおよび更新方法をテストしたいです。だから私はその後、私は、コードを実行session.save(student);を削除し、

student=(Student)session.get(Student.class, 1); 
System.out.println("Student Object have student name as:"+student.getName()); 

student.setName("Chang_update"); 
session.update(student); 

を追加し、<property name="hbm2ddl.auto">update</property>を変更しました。 getメソッドはReturn Changとうまく動作します。しかし、更新メソッドのために、私はそれが古いデータを置き換えると思った。しかし、Chang_updateという新しい学生が1のRollNoで出てきました。古いChangのRollNoは2になりました。

私は休止状態になっています。あなたは私にここで何が起こっているのかヒントを教えてくれますか?

答えて

0

これは問題ではないと思っていますが、Hibernateが並行処理を正しく行えるように@Versionカラムを指定する必要があります。

GenerationType.AUTOの@Idは、HibernateにPKを管理させます。 idフィールドはint(プリミティブ)とInteger(nullを持つことができる)であるため、そこには常にゼロの値があります。したがって、これが新しい行かどうかをhibernateが知ることは可能ではなく、毎回新しいものを作成する必要があるとは思わないでください。何らかの理由で、すでに1のPKがあることを知っていて、

AUTOに完全には慣れていませんが、idフィールドをIntegerに変更し、シーケンスオブジェクトの生成を使用することをお勧めします。

+0

私はAUTOを削除します、それは動作します! – Doris

+0

すべての 'AUTO'の影響は、HibernateがPK値をどのように管理するかです。これは、あるデータベースがシーケンス、その他のidentity/auto_incrementカラムなどに基づいている可能性があることを意味します。 'AUTO'は、データベースがすべてのデータベースベンダーの特定のアプローチではなく、選択方法を指示するようにHibernateに指示します。あなたの問題は@ScottSosnaが言ったように、あなたのPK値はプリミティブではなくオブジェクト型でなければなりません。 – Naros

関連する問題