主表:Topic,主键:topicId,主键为自增长
子表:Reply,主键:replyId,主键设置assigned,外健:topicId
也就是主表和子表关联的字段为topicId
在hbm.xml中one-to-many 和many-to-one设置都没有错(向*保证)
程序大概意思就这样:
Topic topic = new Topic();
Reply reply = new Reply();
reply.setReplyId("xxxx1");
reply.setTopic(topic);
topic.getReplys().add(reply);
session.save(topic);
按道理这时主表和子表都应该保存,但主表操作成功,子表操作失败,看后台的sql语句,对子表的操作居然是update!(难道是设置了子表的主键造成的??)
我把程序稍微改了一下
将子表主键设为uuid.hex,同时去掉reply.setReplyId("xxxx1");这一句,程序就不会出错。
一直在用hibernate,但都没有时间去搞清楚其内部机制,哪位大大知道的说一下。
12 个解决方案
#1
没有人知道吗?
#2
jf
#3
这年头,jf的人多了,解决问题的人却少了
#4
再顶
#5
好久没用HIB了,我没记错的话assigned应该是由你的程序来指定一个KEY给VO对象,你每次插入记录时KEY都是xxxx1,那不是冲突了,当然报错了。uuid.hex是由HIB自动生成一个不重复的KEY,好好看看错误信息是什么,我估计应该是这个原因。
#6
你的reply.setReplyId("xxxx1");是每次不一样吗?比如会冲突啊
#7
to:loverface(双面人)
谢谢你的回复,不过我还不至于这么菜,上面只不过是我举的一个例子而已。
主要问题在于后台打印的sql语句成了update,而不是insert
谢谢你的回复,不过我还不至于这么菜,上面只不过是我举的一个例子而已。
主要问题在于后台打印的sql语句成了update,而不是insert
#8
当一个持久化对象有主键(ID)值时,hibernate就会把它当成是分离对象,也就是数据库中有对应的记录,所以会调用update。
其实hibernate才不管你是调用save还是update还是saveOrUpdate,他只是管理对象状态,他认为是新的对象(没有ID),就用insert,已存在对象(有ID)就用update.
这个ID叫做持久化标识符,你也可以在映射文件中设置当ID值等什么时,该对象为未持久化状态,默认是当o.getId()==null,时就会insert,else update
其实hibernate才不管你是调用save还是update还是saveOrUpdate,他只是管理对象状态,他认为是新的对象(没有ID),就用insert,已存在对象(有ID)就用update.
这个ID叫做持久化标识符,你也可以在映射文件中设置当ID值等什么时,该对象为未持久化状态,默认是当o.getId()==null,时就会insert,else update
#9
既然你认为你的多对一、一对多设置没有问题,那你说说看一对多的replys中的cascade和inverse是什么作用,还是去搞搞清楚吧
#10
to:lujh99(闲云)
多对一,一对多设置是没有问题的,不然修改后会出错
cascade是设置级联的,这里我设的是save-update,因为数据库上面设置了外健
inverse用夏昕的话说就是让全国人民记住胡*的名字,而不是胡*来记住全国人民的名字
不知道我理解得对不
多对一,一对多设置是没有问题的,不然修改后会出错
cascade是设置级联的,这里我设的是save-update,因为数据库上面设置了外健
inverse用夏昕的话说就是让全国人民记住胡*的名字,而不是胡*来记住全国人民的名字
不知道我理解得对不
#11
guzuoshantou(孤小小) 说得好像有道理
因为之前设置了id值,hibernate就把它当成已存在的对象了,所以用了update
等有空了再好好研究一下
因为之前设置了id值,hibernate就把它当成已存在的对象了,所以用了update
等有空了再好好研究一下
#12
8楼说的不对吧,如过我们只是对一个实体类的持久化进行操作,它的主键就是assigned,而且没有任何关联,如果持久化前我们手动写入一个不重复的主键ID,如果按照你的分析,它执行的是update操作所以不能保存到数据库中的喽。
我认为hibernate应该是先判断我们的主键类型,然后再判断主键是否为空的吧。
我认为hibernate应该是先判断我们的主键类型,然后再判断主键是否为空的吧。
#1
没有人知道吗?
#2
jf
#3
这年头,jf的人多了,解决问题的人却少了
#4
再顶
#5
好久没用HIB了,我没记错的话assigned应该是由你的程序来指定一个KEY给VO对象,你每次插入记录时KEY都是xxxx1,那不是冲突了,当然报错了。uuid.hex是由HIB自动生成一个不重复的KEY,好好看看错误信息是什么,我估计应该是这个原因。
#6
你的reply.setReplyId("xxxx1");是每次不一样吗?比如会冲突啊
#7
to:loverface(双面人)
谢谢你的回复,不过我还不至于这么菜,上面只不过是我举的一个例子而已。
主要问题在于后台打印的sql语句成了update,而不是insert
谢谢你的回复,不过我还不至于这么菜,上面只不过是我举的一个例子而已。
主要问题在于后台打印的sql语句成了update,而不是insert
#8
当一个持久化对象有主键(ID)值时,hibernate就会把它当成是分离对象,也就是数据库中有对应的记录,所以会调用update。
其实hibernate才不管你是调用save还是update还是saveOrUpdate,他只是管理对象状态,他认为是新的对象(没有ID),就用insert,已存在对象(有ID)就用update.
这个ID叫做持久化标识符,你也可以在映射文件中设置当ID值等什么时,该对象为未持久化状态,默认是当o.getId()==null,时就会insert,else update
其实hibernate才不管你是调用save还是update还是saveOrUpdate,他只是管理对象状态,他认为是新的对象(没有ID),就用insert,已存在对象(有ID)就用update.
这个ID叫做持久化标识符,你也可以在映射文件中设置当ID值等什么时,该对象为未持久化状态,默认是当o.getId()==null,时就会insert,else update
#9
既然你认为你的多对一、一对多设置没有问题,那你说说看一对多的replys中的cascade和inverse是什么作用,还是去搞搞清楚吧
#10
to:lujh99(闲云)
多对一,一对多设置是没有问题的,不然修改后会出错
cascade是设置级联的,这里我设的是save-update,因为数据库上面设置了外健
inverse用夏昕的话说就是让全国人民记住胡*的名字,而不是胡*来记住全国人民的名字
不知道我理解得对不
多对一,一对多设置是没有问题的,不然修改后会出错
cascade是设置级联的,这里我设的是save-update,因为数据库上面设置了外健
inverse用夏昕的话说就是让全国人民记住胡*的名字,而不是胡*来记住全国人民的名字
不知道我理解得对不
#11
guzuoshantou(孤小小) 说得好像有道理
因为之前设置了id值,hibernate就把它当成已存在的对象了,所以用了update
等有空了再好好研究一下
因为之前设置了id值,hibernate就把它当成已存在的对象了,所以用了update
等有空了再好好研究一下
#12
8楼说的不对吧,如过我们只是对一个实体类的持久化进行操作,它的主键就是assigned,而且没有任何关联,如果持久化前我们手动写入一个不重复的主键ID,如果按照你的分析,它执行的是update操作所以不能保存到数据库中的喽。
我认为hibernate应该是先判断我们的主键类型,然后再判断主键是否为空的吧。
我认为hibernate应该是先判断我们的主键类型,然后再判断主键是否为空的吧。