抛出TransientObjectException异常

org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance - save the transient instance before flushing: com.telecom.model.Admin; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.telecom.model.Admin


	}
多对一 存储(先存储group(对象持久化状态后,再保存user)):
      session = HibernateUtils.getSession();
			tx = session.beginTransaction();

			Group group = new Group();
			group.setName("wjt276");
			session.save(group); //存储Group对象。
			
			User user1 = new User();
			user1.setName("菜10");
			user1.setGroup(group);//设置用户所属的组
			
			User user2 = new User();
			user2.setName("容祖儿");
			user2.setGroup(group);//设置用户所属的组
			
			//开始存储
			session.save(user1);//存储用户
			session.save(user2);
						
			tx.commit();//提交事务
执行后hibernate执行以下SQL语句:
Hibernate: insert into t_group (name) values (?)
Hibernate: insert into t_user (name, groupid) values (?, ?)
Hibernate: insert into t_user (name, groupid) values (?, ?)
注意:如果上面的session.save(group)不执行,则存储不存储不成功。则抛出TransientObjectException异常。
因为Group为Transient状,Object的id没有分配值。2610644

结果:persistent状态的对象是不能引用Transient状态的对象

  以上代码操作,必须首先保存group对象,再保存user对象。我们可以利用cascade(级联)方式,不需要先保存group对象。而是直接保存user对象,这样就可以在存储user之前先把group存储了。
	利用cascade属性是解决TransientObjectException异常的一种手段。
重要属性-cascade(级联):
	级联的意思是指定两个对象之间的操作联运关系,对一个 对象执行了操作之后,对其指定的级联对象也需要执行相同的操作,取值:all、none、save_update、delete
all:代码在所有的情况下都执行级联操作
none:在所有情况下都不执行级联操作
save-update:在保存和更新的时候执行级联操作
delete:在删除的时候执行级联操作。

xml
		例如:<many-to-one name="group" column="groupid" cascade="save-update"/>
annotation
cascade属性:其值:	CascadeType.ALL			所有
CascadeType.MERGE		save + update
CascadeType.PERSIST	    存储产生级联	
CascadeType.REFRESH      刷新的时候产生级联
CascadeType.REMOVE      删除情况下
	例如:
		@ManyToMany(cascade={ CascadeType.ALL})

注意:cascade只是帮我们省了编程的麻烦而已,不要把它的作用看的太大
多对一  加载数据
代码如下:
      session = HibernateUtils.getSession();
			tx = session.beginTransaction();
			
			User user = (User)session.load(User.class, 3);
			System.out.println("user.name=" + user.getName());
			System.out.println("user.group.name=" + user.getGroup().getName());
		
			//提交事务
			tx.commit();
执行后向SQL发出以下语句:
Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_, user0_.groupid as groupid0_0_ from t_user user0_ where user0_.id=?
Hibernate: select group0_.id as id1_0_, group0_.name as name1_0_ from t_group group0_ where group0_.id=?

可以加载Group信息:因为采用了<many-to-one>这个标签,这个标签会在多的一端(User)加一个外键,指向一的一端(Group),也就是它维护了从多到一的这种关系,多指向一的关系。当你加载多一端的数据时,它就能把一的这一端数据加载上来。当加载User对象后hibernate会根据User对象中的groupid再来加载Group信息给User对象中的group属性。




我的解决办法是在管理数据库表里面加   cascade=CascadeType.ALL


你可能感兴趣的:(Hibernate,exception,object,user,存储,insert)