关于jpa添加一对多数据时外键值为空的问题
在使用save方法进行添加操作时,由于某些情况下数据是直接从前端得到,所以,该主键实体对象的id为null(Integer或者Long类型),此时其对应的外联实体对象可能直接保存在该实体类对象中,就像买一把玩具手枪会带一包枪子一样,不是从库中获取的。此时外联对象中的外键也为null,所以在调用save方法时,外联对象进行添加时会出现为外键null的情况,如果设置了外键不为null就会报错,解决的一个方法是:将外键字段设为可以为null,在主键实体对象调用save方法后获取该主键实体对象的所有外键实体对象,遍历所有对象,将其对应的属性设置为主键实体对象(一定要在主键实体对象调用了save方法之后,此时主键实体对象中的id属性就被赋值了),然后逐个调用save方法进行update。
主键类:
1 @Entity 2 @Table(name = "CPAQXPG") 3 @SequenceGenerator(name = "TES_TONE_SEQ", sequenceName = "TEST_ONE_SEQ") 4 public class TestOneEntity implements Serializable { 5 6 @Id 7 @Column(name = "ID") 8 //@GenericGenerator(name = "TEST_ONE_SEQ", strategy = "increment") 9 @GeneratedValue(strategy = GenerationType.AUTO, generator = "TEST_ONE_SEQ") 10 private Integer id; 11 12 @Column(name = "CREATE_BY") 13 private String createBy; 14 15 @OneToMany(targetEntity = TestTwoEntity.class,cascade = CascadeType.ALL,mappedBy = "testOne") 17 private List<TestTwoEntity> testTwos = new ArrayList<>(); 18 19 }
外键类:
1 @Entity 2 @Table(name = "TEST_TWO_PHASE") 3 @SequenceGenerator(name = "TEST_TWO_SEQ", sequenceName = "TEST_TWO_SEQ") 4 public class TestTwoEntity implements Serializable{ 5 6 @Id 7 @Column(name = "ID") 8 @GeneratedValue(strategy = GenerationType.AUTO, generator = "TEST_TWO_SEQ") 9 private Integer id; 10 11 @Column(name = "STORAGE_TEMP") 12 private String storageTemp; 13 14 //STORAGE_TIME与数据库关键字重复,所以加_SUB来区分 15 @Column(name = "STORAGE_TIME_SUB") 16 private String storageTime; 17 18 //与TestOneEntity建立映射关系,id为TestOneEntity中的id属性 19 @ManyToOne(targetEntity = TestOneEntity.class,fetch = FetchType.EAGER) 20 @JoinColumn(name = "C_ID") 21 private TestOneEntity testOne; 22 23 }
Dao层:
1 @Repository 2 public class TestOneDao extends HibernateDao< TestOneEntity,Integer> { 3 4 }
Service层:
1 @Service 2 @Transactional 3 public class TestOneService extends BaseService<TestOneEntity,Integer> { 4 @Autowired 5 private TestOneDao testOneDao; 6 7 @Override 8 public HibernateDao<TestOneEntity, Integer> getEntityDao() { 9 return testOneDao; 10 } 11 12 }
控制层方法:
1 @Service 2 @Transactional 3 public class TestOneService extends BaseService<TesetOneEntity,Integer> { 4 @Autowired 5 private TestOneDao testOneDao; 6 7 public String addTestOne(HttpServletRequest request,TestOneEntity testOneEntity) { 8 9 testOneService.save(testOneEntity); 10 List<TestTwoEntity> testTwos = testOneEntity.getTestTwos();
12 for (TestTwoEntity testTwo : testTwos) { 13 testTwo.setTestOne(testOneEntity); 14 testTwoService.save(testTwo);
16 }
// 或者遍历将OneEntity实例set之后,使用批量插入 17 18 } 19 20 }