jpa中一对多的级联增删改

以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();
	}
从表数据都可以随便删。对于主表,配置了级联删除的时候,连从表数据一块儿删;如果没配置级联删除,当从表没对应数据的时候,能正常删除,若从表有对应数据,删除失败!


猜你喜欢

转载自blog.csdn.net/dimples_qian/article/details/80905998
今日推荐