iteye_8573 2009-01-07 19:34
浏览 257
已采纳

hibernate中单向多对一的关联疑惑(管理员勿将帖子转到问答,那里不好交流)

本人初学hibernate,希望大家多多指教!

我假设person和card的多对一的关系(实际这两者的关系不是多对一)

他们对应的映射文件是:

person.hbm.xml

<!---->

<hibernate-mapping schema="hibernatequickuse">
<class name="mypack.person" table="person">
<id name="id" column="id" type="java.lang.Integer">
<generator class="identity">
</id>
<property name="name" column="name" type="java.lang.String" not-null="true"></property>
<many-to-one name="mycard" column="card_id" class="mypack.Card" cascade="all"></many-to-one>
</class>
</hibernate-mapping>



Card.hbm.xml

<!---->

<hibernate-mapping>
<class name="mypack.Card" table="card">
<id name="id" column="ID" type="java.lang.Integer">
<generator class="identity">
</id>
<property name="name" column="NAME" type="java.lang.String" not-null="true"></property>
</class>
</hibernate-mapping>



假设当我们先把many-to-one中的cascade属性值去掉,改为:

<many-to-one name="mycard" column="card_id" class="mypack.Card"></many-to-one>


然后执行如下代码:

  person p=new person();
p.setName("jack01");
Card c=new Card();
c.setName("card0031");
p.setMycard(c);
Session session=null;
Transaction tran=null;
try{
session=factory.openSession();
tran=session.beginTransaction();
session.save(p);//为什么是update,而不是Insert
tran.commit();
。。。。。。。



执行结果本来应该会报一个异常,因为只持久化了person对象。而card是临时对象,所以当hibernate自动清理缓存中的持久化对象时会发现p引用了c临时对象,而在person表中对应的card_id字段值为0,这说明person持久化对象的状态和数据库的记录不一致,所以应该会抛出异常!但是它却并没有抛出异常,

而是插入了一条person记录,其card_id=0这是为什么???

Hibernate: insert into hibernatequickuse.person (name, card_id) values (?, ?)


当我把cascade="all"加上去之后,本来这时应该是先插入card记录,然后插入Person记录。但结果却是:

Hibernate: insert into hibernatequickuse.person (name, card_id) values (?, ?)
Hibernate: update card set NAME=? where ID=?


而且抛出异常,表示无法更新!这又是为什么????????

Exception executing batch: 
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1


表结构如下:

-- 

-- 表的结构 card

CREATE TABLE card (
id int(11) NOT NULL auto_increment,
name varchar(20) collate latin1_general_ci NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=7 ;

CREATE TABLE person (
id int(11) NOT NULL auto_increment,
name varchar(32) collate latin1_general_ci NOT NULL,
card_id int(11) unsigned NOT NULL,
PRIMARY KEY (id),
KEY card_id (card_id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=4 ;



POJO如下:

person

package mypack;
public class person implements java.io.Serializable{
private int id;
private String name;
private Card mycard;

public person(){

}
private void setId(int id){
    this.id=id;
}
public void setName(String name){
    this.name=name;
}
public void setMycard(Card mycard){
    this.mycard=mycard;
}
public int getId(){
    return this.id;
}
public String getName(){
    return this.name;
}
public Card getMycard(){
  return this.mycard;
}

}





Card

package mypack;

public class Card {
private int id;
private String name;

public Card(){

}
public void setId(int id){
this.id=id;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return this.name;
}
public int getId(){
return this.id;
}
}






问题补充
补充下:我是参照网友的教程来做的,地址是:http://ryanpoy.iteye.com/blog/189783

奇怪的是他的结果是正确的!程序里面唯一不同的是我主键的设置上,我用的是auto_increment,映射xml中用的是identity!




问题补充:
谢谢kulinglei的回答,问题是我将cascade="save-update"; 它也没报任何异常啊,正常的情况应该是会报你所说的异常啊 !我把源码上传下,能帮我看看吗?
问题补充:
这是源码,希望大家帮帮忙!
问题补充:
谢谢etank帮忙,但我也用的是hibernate3的包,并且把identity改为了native。把cascade设为none,结果还是没报任何异常啊?我用的是mysql的数据库
  • 写回答

6条回答 默认 最新

  • etank2011 2009-01-08 10:47
    关注

    晕,排版不象我想象的,反而搞乱了
    区别是,原文用的hibernate3
    http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd
    lz用的hibernate2
    http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题