论坛首页 Java企业应用论坛

one-many的映射,mySQL服务器,必须每次从新建表,请问是为蔦\0...

浏览 8366 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2004-01-29  
one-many的映射,mySQL服务器,必须每次从新建表,请问是为什么?

当加上语句:
SchemaExport dbExport=new SchemaExport(conf);
dbExport.setOutputFile("e:sql.txt");
dbExport.create(true, true);

则运行正确,否则报错:

警告: SQL Error: 1062, SQLState: S1009
2004-1-29 16:31:52 net.sf.hibernate.util.JDBCExceptionReporter logExceptions
严重: Invalid argument value: Duplicate entry '0' for key 1
2004-1-29 16:31:52 net.sf.hibernate.JDBCException <init>
严重: could not insert collection: [hibernate.Company.employees#402881a0fa60c16800fa60c16b500001]
java.sql.SQLException: Invalid argument value: Duplicate entry '0' for key 1
at org.gjt.mm.mysql.MysqlIO.sendCommand(Unknown Source)
at org.gjt.mm.mysql.MysqlIO.sqlQueryDirect(Unknown Source)
at org.gjt.mm.mysql.Connection.execSQL(Unknown Source)
at org.gjt.mm.mysql.PreparedStatement.executeUpdate(Unknown Source)
at org.gjt.mm.mysql.PreparedStatement.executeUpdate(Unknown Source)
at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
at net.sf.hibernate.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:559)
at net.sf.hibernate.impl.ScheduledCollectionRecreate.execute(ScheduledCollectionRecreate.java:23)
at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2362)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2320)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2258)
at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:57)
at hibernate.TestCompany.main(TestCompany.java:61)
2004-1-29 16:31:52 net.sf.hibernate.impl.SessionImpl execute
严重: Could not synchronize database state with session
net.sf.hibernate.JDBCException: could not insert collection: [hibernate.Company.employees#402881a0fa60c16800fa60c16b500001]
at net.sf.hibernate.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:577)
at net.sf.hibernate.impl.ScheduledCollectionRecreate.execute(ScheduledCollectionRecreate.java:23)
at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2362)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2320)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2258)
at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:57)
at hibernate.TestCompany.main(TestCompany.java:61)
Caused by: java.sql.SQLException: Invalid argument value: Duplicate entry '0' for key 1
at org.gjt.mm.mysql.MysqlIO.sendCommand(Unknown Source)
at org.gjt.mm.mysql.MysqlIO.sqlQueryDirect(Unknown Source)
at org.gjt.mm.mysql.Connection.execSQL(Unknown Source)
at org.gjt.mm.mysql.PreparedStatement.executeUpdate(Unknown Source)
at org.gjt.mm.mysql.PreparedStatement.executeUpdate(Unknown Source)
at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
at net.sf.hibernate.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:559)
... 6 more
net.sf.hibernate.JDBCException: could not insert collection: [hibernate.Company.employees#402881a0fa60c16800fa60c16b500001]
at net.sf.hibernate.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:577)
at net.sf.hibernate.impl.ScheduledCollectionRecreate.execute(ScheduledCollectionRecreate.java:23)
at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2362)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2320)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2258)
at net.sf.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:57)
at hibernate.TestCompany.main(TestCompany.java:61)
Caused by: java.sql.SQLException: Invalid argument value: Duplicate entry '0' for key 1
at org.gjt.mm.mysql.MysqlIO.sendCommand(Unknown Source)
at org.gjt.mm.mysql.MysqlIO.sqlQueryDirect(Unknown Source)
at org.gjt.mm.mysql.Connection.execSQL(Unknown Source)
at org.gjt.mm.mysql.PreparedStatement.executeUpdate(Unknown Source)
at org.gjt.mm.mysql.PreparedStatement.executeUpdate(Unknown Source)
at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:22)
at net.sf.hibernate.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:559)
... 6 more
   发表时间:2004-01-29  
请问是不是因为mySQL的问题呢?
0 请登录后投票
   发表时间:2004-01-30  
不是因为mysql的问题,错误中不是说了么,主键重复么,
引用
SchemaExport dbExport=new SchemaExport(conf);
dbExport.setOutputFile("e:sql.txt");
dbExport.create(true, true);

上面这三句是建表用的,你加上后,每次运行都重新建表,所以不会出错,当你去掉以后,因为你表中已经有一条数据,而这个时候,你有录入相同的数据,由于主键重复,所以无法录入。
0 请登录后投票
   发表时间:2004-01-30  
aloneflasher:感谢您的回复,但是即使我加入了新的记录,还是会出错!

我建的表是2个,一个是COMPANY,一个是PERSON,COMPANY有2个字段,而PERSON有一个外键就是引用了COMPANY的主键,COMPANY的主键是HIBERNATE给的,很随机,而PERSON的主键则变成了0,1,2等,在我去掉从新建表的语句后,出错,但相应的数据已经插入到了表中,只是PERSON没有外键(为空)了。

烦清帮助解答!
0 请登录后投票
   发表时间:2004-02-02  
不能同步session和数据库...这个错偶也遇到过...
1.你再仔细看一下你的配置文件...有什么地方可能你没有注意....
2.是否有的property是非空的...而你传入的对象的property是null呢?
0 请登录后投票
   发表时间:2004-02-02  
3.当你修改配置文件后...没有重新建立数据库....这时session和数据库当然不能同步
4.数据库的完整性被破坏掉了....例如...我们在数据库中有company1和person1,person2,他们是一对多的关系...这时我们直接在数据库里(不通过hibernate)删除company1...这时person1和person2的外键还存在...也会出现这个错....

有半个月都8用hibernate了....偶都8记得了.....
你看看有用没有....
0 请登录后投票
   发表时间:2004-02-02  
感谢kappa的热心!

我的问题我分析是这样的:我的PERSON表的主键是它的ID,外键是COMPANY的主键,对于PERSON的配置文件,它的GENERATOR是UUID.DEX,然而生成PERSON对象的时候主键却成了1、2、3之类的,在第二次执行程序的时候,还是从1开始产生主键,就出错了,不知道配置文件的GENERATOR该怎么写呢?

谢谢!
0 请登录后投票
   发表时间:2004-02-02  
一般兼容性比较好的id生成方式是uuid.hex,这样生成的id不会重名:
举一个小例子:
        <id
            name="userID"
            column="user_id"
            unsaved-value="null"
        >
            <generator class="uuid.hex"/>
        </id>
0 请登录后投票
   发表时间:2004-02-02  
package hibernate;

public class Person {
	private String id ;
	private String name ;
	private String address ;
	
	public String getAddress(); {
		return address;
	}

	public String getId(); {
		return id;
	}

	public String getName(); {
		return name;
	}

	public void setAddress(String string); {
		address = string;
	}

	public void setId(String string); {
		id = string;
	}

	public void setName(String string); {
		name = string;
	}

}


<hibernate-mapping>
	<!--默认是表的名字和类的名字一样-->
	<class name="hibernate.Person">
	    <!--hibernate为我们生成主键id-->
	    <!--如果不写column的属性,就默认和列的名字一样-->
		<id name = "id">
			<generator class="uuid.hex"/>
		</id>
		
	    <!--默认把类的变量映射为相同名字的表列,当然我们可以修改其映射方式-->
		<property name="name" column="name" type="java.lang.String"/>
		<property name="address" column="address" type="java.lang.String"/>
	</class>
</hibernate-mapping>


package hibernate;

import java.util.List;
import java.util.Vector;

public class Company {
	private String id ;
	private String name ;
	private List employees = new Vector(); ;
	/**
	 * @return
	 */
	public List getEmployees(); {
		return employees;
	}

	/**
	 * @return
	 */
	public String getId(); {
		return id;
	}

	/**
	 * @return
	 */
	public String getName(); {
		return name;
	}

	/**
	 * @param list
	 */
	public void setEmployees(List list); {
		employees = list;
	}

	/**
	 * @param string
	 */
	public void setId(String string); {
		id = string;
	}

	/**
	 * @param string
	 */
	public void setName(String string); {
		name = string;
	}

	public void addEmployee(Person p);{
		employees.add(p);;
	}
	
	public void removeEmployee(Person p);{
		employees.remove(p);;
	}
	
	public void clearEmployees();{
		employees.clear(); ;
	}
}


<hibernate-mapping>
	<class name="hibernate.Company">
	    <!--hibernate为我们生成主键id-->
	    <!--如果不写column的属性,就默认和列的名字一样-->
		<id name = "id" unsaved-value = "null">
			<generator class="uuid.hex"/>
		</id>
		
        <property name="name"/>
	    <!--1:n关系的映射-->
	    <!--在持久化对象中使用了List接口就是list,如果使用了Set接口就用set-->
	    <list name="employees" cascade="all">
            <key column="company_id"/>
            <index column="id"/>
            <one-to-many class="hibernate.Person"/>
        </list>
	</class>
</hibernate-mapping>


package hibernate;

import net.sf.hibernate.Session;
import net.sf.hibernate.Transaction;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.cfg.Configuration;
import net.sf.hibernate.tool.hbm2ddl.SchemaExport;

public class TestCompany {
	private static SessionFactory sessions;

	public static void main(String[] args); throws Exception{        	
		//配置环境,分析xml映射文件
		Configuration conf= new Configuration();
			.addClass(Person.class);
			.addClass(Company.class);;
        
		//生成并输出sql到文件(当前目录)和数据库
//		SchemaExport dbExport=new SchemaExport(conf);;
//		dbExport.setOutputFile("e:sql.txt");;
//		dbExport.create(true, true);;
 
		sessions = conf.buildSessionFactory();;
		//以上都是些固定格式的环境配置
        
		//start......
		Session s = sessions.openSession();;
		Transaction t = s.beginTransaction();;
	    
		//1.用普通方式建立对象,填充数据
		Company c=new Company();;
		c.setName("东软");;
	    
		Person p1=new Person();;
		p1.setName("陈鹏");;
		p1.setAddress("西安东郊黄陵");;

		Person p2=new Person();;
		p2.setName("孙昱鹏");;
		p2.setAddress("南郊电子城");;

		c.addEmployee(p1);;
		c.addEmployee(p2);;
	    
		//2.持久化

		s.save(c);;
		//此时c,p1,p2已经可以在数据库中找到
  
		t.commit();;
		s.close();;
	}

}
0 请登录后投票
   发表时间:2004-02-02  
对应上面的例子,我在第一次执行TESTCOMPANY的时候执行下面的语句,然后就将它注释掉,再次执行TESTCOMPANY就抛出了顶层帖子的异常内容。我不可能每次都要从新建表,而且我也需要保存从前输入的内容,那我应该怎么办呢?

//生成并输出sql到文件(当前目录)和数据库 
//      SchemaExport dbExport=new SchemaExport(conf);; 
//      dbExport.setOutputFile("e:sql.txt");; 
//      dbExport.create(true, true);; 
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics