SAS 发表于 2012-08-17 15:16

一个hibernate和H2数据库奇怪的问题

最近在研究h2数据库,昨天发现个奇怪的问题:
先看看用到的类里面的代码:
自己写的Hibernate类,用来查询,插入数据等操作。
public class HibernateDB {
        SessionFactory sessionFactory;
       Session session=null;
       
        public HibernateDB(String cfgfile){
               
                sessionFactory = new AnnotationConfiguration().configure(cfgfile).buildSessionFactory();
               
        }
public boolean Commit(){
               
               
                try {
                       
                        session.flush();
                session.getTransaction().commit();
                this.ReConnected();

               
                return true;
               
                } catch (HibernateException e) {
                        e.printStackTrace();
                        System.out.println("数据库提交数据错误................");
                        return false;
                }
        }
public boolean InsertObj(Object obj){
               
                try {
               
                        session.saveOrUpdate(obj);
                       
                        return true;
                } catch (HibernateException e) {
                       
                        System.out.println("数据库写入错误-----");
                        e.printStackTrace();
                        return false;
                }
        }
}

public List GetListHql(String Hqlstr){
                //System.out.println("提交给数据库的语句:"+Hqlstr);
                isConnected();
                List tmp = session.createQuery(Hqlstr).list();
                //session.close();
                return tmp;
        }
}

自己写的H2数据库类,用来启动,停止数据库的操作
public class H2MenDateBase {
       
        Server server=null;
       
        public void start()
        {
               try {
                       
                        server= Server.createTcpServer(new String[] { "-tcpPort", "9092" } ).start();
                       
                } catch (SQLException e) {
                       
                        e.printStackTrace();
                }
        }
}

在代码中我使用Hibernate链接H2数据库
Hibernate的配置文件大致如下:
<property name="use_sql_comments">true</property>
        <property name="hibernate.hbm2ddl.auto">create</property><!--自动创建表-->
        <property name="hibernate.show_sql">true</property><!--显示的sql语句格式化-->
<!-- <property name="format_sql">true</property>使显示的sql语句-->
        <property name="jdbc.use_streams_for_binary">true</property>
        <property name="myeclipse.connection.profile">ora_new</property>
        <property name="connection.url">
        <!--        jdbc:oracle:thin:@135.32.92.12:1521:ynnms -->
        jdbc:h2:tcp://localhost/mem:memtable   <!--使用内存的方式-->
        </property>
        <!--<property name="connection.username">inms</property>
        <property name="connection.password">inms123</property> -->
        <property name="connection.username">sa</property>
        <property name="connection.password"></property>
        <property name="connection.driver_class">
                org.h2.Driver
        </property>
        <property name="dialect">
                org.hibernate.dialect.H2Dialect
        </property>


用来测试的数据类如下:
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;


@Entity
@Table(name = "TestTable")
public final class TestTable {
        @Id
        String BID;// NUMBER(16) not null,
        String username;// VARCHAR2(64) not null,
        String pass;// VARCHAR2(128) not null,
        public String getBID() {
                return BID;
        }
        public void setBID(String bID) {
                BID = bID;
        }
        public String getUsername() {
                return username;
        }
        public void setUsername(String username) {
                this.username = username;
        }
        public String getPass() {
                return pass;
        }
        public void setPass(String pass) {
                this.pass = pass;
        }
        public void show(){
                System.out.println("id="+BID+"\tusername="+username+"\tpass="+pass);
        }
}
       
下面的代码是对数据库进行插入,然后查询数据的一个操作
public static void main(String[] args) {
                H2MenDateBase h2d=new H2MenDateBase();
                h2d.start();
                HibernateDB hbh2=new HibernateDB("/hibernate-h2.cfg.xml");
                TestTable tt=new TestTable();
                //List aa=null
                //int i=0;
                //String Sqlstr="create table TestTable(BID   VARCHAR2(62), userNAME VARCHAR2(62),pass varchar2(64))";
                //hbh2.PutSQl(Sqlstr);
                for(int i=1;i<=100;i++){
                        tt.setBID(i+"");
                        tt.setUsername("mabin"+i);
                        tt.setPass("mabin"+i);
                        System.out.print("-------");
                        tt.show();
                       
                        hbh2.InsertObj(tt);
                        hbh2.Commit();
                }
               
               
//       
//               
                List ttlist=hbh2.GetListHql("from TestTable");
               for( Object ttmp: ttlist){
                       TestTable tt2=(TestTable) ttmp;
                       tt2.show();
               }
                }

奇怪的是hbh2.Commit(); 这个语句,当这个语句防止在循坏内的话,程序运行正常,没有报错。
但hbh2.Commit();这个语句放置到循坏外的话,就报告如下的错误
org.hibernate.HibernateException: identifier of an instance of com.DBTable.TestTable was altered from 1 to 100


很是奇怪,请高手解释下原因。另外,如果hbh2.Commit(); 每个循环都执行一次是否会影响到性能?


谢谢!

SAS 发表于 2012-08-17 17:36

:sleepy::sleepy::sleepy::sleepy:

_Rayx 发表于 2012-08-19 20:40

估计是因为在for里面的时候,每次插入新对象,而放在外面,hibernate认为这是一个对象,而你把主键更新了,所以报错。
页: [1]
查看完整版本: 一个hibernate和H2数据库奇怪的问题