jpa中一对多的级联增删改

本文介绍了JPA中一对多关系的级联增删改操作,以Customer和Contact表为例。在进行操作时,若不配置级联更新,可能会遇到瞬时态对象操作持久态对象导致的错误。正确做法是结合使用级联更新和mappedBy属性,以确保数据库中的关联关系得到正确维护。级联删除的设置也进行了讨论。

以Customer表和Contact表为例:

新增:

//一对多增加
	@Test
	public void testPersist() {
		Customer customer = new Customer();
		customer.setName("新客户");
		Contact contact = new Contact();
		contact.setName("新联系人");
		//添加双向关联关系
		customer.getContacts().add(contact);
		contact.setCustomer(customer);
		
		EntityManager em = MyJPAUtils.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		em.persist(customer);//我已经在客户上配置了级联属性,所以这里直接保存customer即可
		tx.commit();
		em.close();
	}

更新:

	//一对多更新
	@Test
	public void testMerge() {
		Contact contact = new Contact();
		contact.setName("联系人4");
		
		EntityManager em = MyJPAUtils.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		Customer customer = em.find(Customer.class, Integer.parseInt("1"));
		customer.getContacts().add(contact);//这一步涉及对象导航查询,所以对应的有个select语句出来
		contact.setCustomer(customer);//这一步不写的话,向数据库中插入的记录外键字段值为null
		//JPA在insert联系人对象的时候直接把customer_id一起插进去了,不会在insert之后出update语句,hibernate则是先insert再update一下
		tx.commit();
		em.close();
	}
在这个测试里,如果我不配置级联更新,也不配置mappedBy,那么主表会去维护关联关系,最后看到维护关联关系的
contact.setCustomer(customer);

时,会发现一个瞬时态的对象操作一个持久态对象,报错!如果不配置级联更新,但是配置了mappedBy,这时候主表放弃维护关联关系,并不会去数据库执行什么操作,不会报错,但是更新目的同时也没达到。(这里注意,contact.setCustomer(customer)这么写是不会报错的,但是如果真的需要去数据库里做对应操作那么执行到这里会报错)。

    所以正确的解决办法是,同时加上级联更新和mappeBy属性!


级联删除:

//一对多删除
	@Test
	public void testRemove() {
		EntityManager em = MyJPAUtils.getEntityManager();
		EntityTransaction tx = em.getTransaction();
		tx.begin();
		Customer c = em.find(Customer.class, Integer.parseInt("3"));
		em.remove(c);
		tx.commit();
		em.close();
	}
从表数据都可以随便删。对于主表,配置了级联删除的时候,连从表数据一块儿删;如果没配置级联删除,当从表没对应数据的时候,能正常删除,若从表有对应数据,删除失败!


评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值