Jpa/Hibernate之级联保存的坑

前两天遇到一个Jpa save的坑,同时保存关联的两个实体时报错,下面举例说明:

有两个类:Group, Customer,他们是One to Many的关系,主键都是由sequence生成,group_id作为t_customer的外键和t_group表关联。示例代码如下:

@Entity
@Table(name = "t_group")
@Data
public class Group {

	@Id
	@SequenceGenerator(name = "test_seq_generator", sequenceName = "group_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "group_seq")
	private Long id;

	private String name;

	@OneToMany(cascade=ALL, mappedBy="group")
	private List customerList;

}
@Entity
@Table(name = "t_customer")
@Data
public class Customer {
	
	@Id
	@SequenceGenerator(name = "test_seq_generator", sequenceName = "customer_seq", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "customer_seq")
	private Long id;
	
	private String name;
	
	@ManyToOne   
	private Group group;

}

坑来了:如果用GroupRepository的save方法进行级联保存,会报can not insert null into t_customer.group_id。意思是插入t_customer时外键为空了。

下面来看一下错误的save代码:

List customerList = new ArrayList<>();
Customer customer = new Customer();
customer.setName("ccc1");
customerList.add(customer);
		
customer = new Customer();
customer.setName("ccc2");
customerList.add(customer);

Group group = new Group();
group.setName("test111");
group.setCustomerList(customerList);
		
groupRepository.save(group);

错位原因很简单,你只是把customerList set到了group中,但是没有给每个customer指定它关联的是哪个group。

这种错误很容易出现在把从web端传过来的dto实体直接copy给db的实体类。

解决方法也很简单:

Group group = new Group();
group.setName("test111");

List customerList = new ArrayList<>();
Customer customer = new Customer();
customer.setName("ccc1");
customer.setGroup(group);    // 给该customer指定它所关联的group
customerList.add(customer);
		
customer = new Customer();
customer.setName("ccc2");
customer.setGroup(group);    // 给该customer指定它所关联的group
customerList.add(customer);


group.setCustomerList(customerList);
		
groupRepository.save(group);

另外还有一个坑,就是效率问题,用jpa的save方法同时保存几百个Group,每个Group下面有多个Customer时会很慢慢慢慢慢,打印出的sql显示,insert或者update Customer前会根据Group ID查询每一个Group,一下子就多了几百个select,哎。还是喜欢用了八年多的Mybatis。

你可能感兴趣的:(JPA)