关于一对多(学生和班级)的一个奇怪问题,很难理解
学生
班级
实体类(学生)
public class Student implements Serializable{
private Integer id;
private String name;
private ClassRoom roomid;
....
班级
public class ClassRoom implements java.io.Serializable{
private Integer id;
private String name;
测试类:
public void testAA5(){
Student ss1=new Student();
ss1.setName("wang34");
Student ss2=new Student();
ss2.setName("wang46");
Set set=new HashSet();
set.add(ss1);
set.add(ss2);
HibernateUtil.beginTransaction();
Session session=HibernateUtil.getCurrentSession();
ClassRoom room=(ClassRoom)session.get(ClassRoom.class,new Integer(1));
room.setSet(set);
ss1.setRoomid(room);
ss2.setRoomid(room);
session.getTransaction().commit();
session.close();
}
这是我的测试类:测试出错了
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
...
Caused by: java.sql.BatchUpdateException: ORA-01407: 无法更新 ("SYSTEM"."STUDENT"."ROOMID") 为 NULL
...
发出一下sql语句:
Hibernate: insert into student (name, roomid, id) values (?, ?, ?)
Hibernate: insert into student (name, roomid, id) values (?, ?, ?)
如果将配置文件里的inverse改为true或者将session.get(ClassRoom.class,new Integer(1));改为session.load(ClassRoom.class,new Integer(1));
程序就没有错了,请高手解释一下原因
我想问的是Hibernate: update student set roomid=null where roomid=?
为什么发出这样的语句,关键是roomid=null,为什么是null
[b]问题补充:[/b]
inverse=false的情况下将set改为load为什么程序也没有错了,这是什么原因
inverse="false"也就是让Student有责任维护关系,也就是先处理Student的持久化,再处理ClassRoom的持久化
双向多对一:
第一方式:inverse=true,则主控方为为Student表,关联关系由被控方维护,也就是说由主表维护。那么你的这段代码
[code="java"]
[color=blue]
Student ss1=new Student();
ss1.setName("wang34");
Student ss2=new Student();
ss2.setName("wang46");
Set set=new HashSet();
set.add(ss1);
set.add(ss2);
Set set=new HashSet();
set.add(ss1);
set.add(ss2);
HibernateUtil.beginTransaction();
Session session=HibernateUtil.getCurrentSession();
ClassRoom room=(ClassRoom)session.get(ClassRoom.class,new Integer(1));
room.setSet(set);
ss1.setRoomid(room);
ss2.setRoomid(room); [/color]
[/code]
改成下面就行啦
[code="java"]
[color=red]
Student ss1=new Student();
ss1.setName("wang34");
Student ss2=new Student();
ss2.setName("wang46");
HibernateUtil.beginTransaction();
Session session=HibernateUtil.getCurrentSession();
ClassRoom room=(ClassRoom)session.get(ClassRoom.class,new Integer(1));
ss1.setRoomid(room);
ss2.setRoomid(room);
[/color]
[/code]
第二种方式:inverse="false",则主控方是ClassRoom,关联关系由Student维护,
那么你的这段代码
[code="java"]
[color=blue]
Student ss1=new Student();
ss1.setName("wang34");
Student ss2=new Student();
ss2.setName("wang46");
Set set=new HashSet();
set.add(ss1);
set.add(ss2);
Set set=new HashSet();
set.add(ss1);
set.add(ss2);
HibernateUtil.beginTransaction();
Session session=HibernateUtil.getCurrentSession();
ClassRoom room=(ClassRoom)session.get(ClassRoom.class,new Integer(1));
room.setSet(set);
ss1.setRoomid(room);
ss2.setRoomid(room); [/color]
[/code]
改成下面就行啦
[code="java"]
[color=red]
Student ss1=new Student();
ss1.setName("wang34");
Student ss2=new Student();
ss2.setName("wang46");
HibernateUtil.beginTransaction();
Session session=HibernateUtil.getCurrentSession();
ClassRoom room=(ClassRoom)session.get(ClassRoom.class,new Integer(1));
Set set = room.getSet();
set.add(ss1);
set.add(ss2);
//下面是多余的,因为是双向,保存一方就行啦。
//ss1.setRoomid(room);
//ss2.setRoomid(room);
[/color]
[/code]
最后建议你再再好好看看Hibernate文档,这个问题是你的对关联关系概念不太清析
load方法也只是一个虚查询,返回一个代理而已,并不是真正去数据库里查询,
inverse=false与get,load根本就扯不上边
inverse是用来维护关联关系的,与记录更新有点关系
get.load是用来查询记录的。