文章目录
  1. 1. spring JPA问题汇总
    1. 1.1. 在做级联保存时报错
    2. 1.2. JPA所有级联默认都会添加一个关联表
    3. 1.3. JPA获取lazy方式加载对象时报错

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
文章目录
  1. 1. spring JPA问题汇总
    1. 1.1. 在做级联保存时报错
    2. 1.2. JPA所有级联默认都会添加一个关联表
    3. 1.3. JPA获取lazy方式加载对象时报错