spring JPA问题汇总
spring JPA问题汇总
在做级联保存时报错
错误信息类似:
cannot be cast to java.io.Serializable
解决办法:
在 Entity中加入 implements Serializable
@Data
@Entity(name = "R_COUPON")
@DynamicUpdate
@DynamicInsert
public class Coupon implements Serializable{
...
}
原因:
Hibernate 有二级缓存, 缓存会将对象写进硬盘。就必须序列化。
为了兼容对象在网络钟的传输。如果不序列化,它就会认为不是同一个对象,就会报那个错。
JPA所有级联默认都会添加一个关联表
如:
@Data
@Entity(name = "R_COUPON")
@DynamicUpdate
@DynamicInsert
public class Coupon implements Serializable{
...
@ManyToMany(cascade = CascadeType.PERSIST)
private List<CouponMerchant> merchantList = new ArrayList<>();
}
test:
@Test
public void testSave(){
Coupon coupon = new Coupon();
coupon.setName("满50减10");
...
List<CouponMerchant> couponMerchantList = new ArrayList<>();
CouponMerchant couponMerchant1 = new CouponMerchant();
...
couponMerchantList.add(couponMerchant1);
coupon.setMerchantList(couponMerchantList);
couponRepository.saveAndFlush(coupon);
}
发出的sql语句为:
Hibernate: insert into r_coupon (amount, code, create_time, end_date, is_all_business, member_id, minimum_spending_amount, name, start_date, status, update_time, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, null)
Hibernate: insert into r_coupon_merchant (merchant_code, merchant_name, id) values (?, ?, null)
Hibernate: insert into r_coupon_merchant (merchant_code, merchant_name, id) values (?, ?, null)
Hibernate: insert into r_coupon_merchant (merchant_code, merchant_name, id) values (?, ?, null)
Hibernate: insert into r_coupon_merchant (merchant_code, merchant_name, id) values (?, ?, null)
Hibernate: insert into r_coupon_merchant_list (r_coupon_id, merchant_list_id) values (?, ?)
Hibernate: insert into r_coupon_merchant_list (r_coupon_id, merchant_list_id) values (?, ?)
Hibernate: insert into r_coupon_merchant_list (r_coupon_id, merchant_list_id) values (?, ?)
Hibernate: insert into r_coupon_merchant_list (r_coupon_id, merchant_list_id) values (?, ?)
Hibernate: insert into r_coupon (amount, code, create_time, end_date, is_all_business, member_id, minimum_spending_amount, name, start_date, status, update_time, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, null)
Hibernate: insert into r_coupon_merchant (merchant_code, merchant_name, id) values (?, ?, null)
Hibernate: insert into r_coupon_merchant (merchant_code, merchant_name, id) values (?, ?, null)
Hibernate: insert into r_coupon_merchant_list (r_coupon_id, merchant_list_id) values (?, ?)
Hibernate: insert into r_coupon_merchant_list (r_coupon_id, merchant_list_id) values (?, ?)
所以有个中间表,默认命名为r_coupon_merchant_list
,是和owner对象中定义的merchantList属性名是有关系的,而且默认用两张表的ID作关联了。
我现在不想用这个默认的中间表,想指定他的关系,不想用默认的ID作为表关联,我要用code作关联。
解决方案:
只要在owner对象中引入的列表属性中加上:
@ManyToMany(cascade = CascadeType.PERSIST)
@JoinTable(name = "R_COUPON_COUPON_MERCHANT",joinColumns = @JoinColumn(name = "COUPON_CODE",referencedColumnName = "CODE"),
inverseJoinColumns = @JoinColumn(name = "MERCHANT_CODE",referencedColumnName = "MERCHANT_CODE"))
private List<CouponMerchant> merchantList = new ArrayList<>();
运行一下打印出的sql:
Hibernate: insert into r_coupon (amount, code, create_time, end_date, is_all_business, member_id, minimum_spending_amount, name, start_date, status, update_time, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, null)
Hibernate: insert into r_coupon_merchant (merchant_code, merchant_name, id) values (?, ?, null)
Hibernate: insert into r_coupon_merchant (merchant_code, merchant_name, id) values (?, ?, null)
Hibernate: insert into r_coupon_coupon_merchant (coupon_code, merchant_code) values (?, ?)
Hibernate: insert into r_coupon_coupon_merchant (coupon_code, merchant_code) values (?, ?)
JPA获取lazy方式加载对象时报错
错误信息:
spring jpa lazy could not initialize proxy - no Session
解决方案:
需要将service端加事务注解(可以在类上,也可以在方法上)
@Transactional