TransientPropertyValueException:对象引用未保存的瞬态实例 - 在查询刷新之前保存瞬态实例

时间:2017-08-20 05:56:00

标签: java spring hibernate

我有两个休眠实体Coupon和CouponHistory与CouponHistory和优惠券之间的单向关系。

@Entity
@Table(name = "validity_coupon")
public class Coupon {

@Id
@Column(length = 50, unique = true, nullable = false)
private String code;

private int validity;
private boolean used;

...}


@Entity
@Table(name = "coupon_history")
@TableGenerator(name = "seqGen", table = "shunya_id_gen", pkColumnName = "GEN_KEY", valueColumnName = "GEN_VALUE",
    pkColumnValue = "coupon_history_seq", allocationSize = 1)
public class CouponHistory {

@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "seqGen")
private long id;

@Temporal(TemporalType.TIMESTAMP)
private Date createdOn;

@ManyToOne(fetch = FetchType.LAZY)
private Coupon coupon;

...}

有一种事务服务方法,它试图在单个事务中保存两个实体。 Spring在这里用来处理交易。

@Transactional
public void createCoupon() {
    Coupon coupon = new Coupon();
    coupon.setCode(RandomStringUtils.randomAlphanumeric(5));
    coupon.setValidity(1);
    couponRepository.save(coupon);

    CouponHistory couponHistory = new CouponHistory();
    couponHistory.setCreatedOn(new Date());
    couponHistory.setCoupon(coupon);
    couponHistoryRepository.save(couponHistory);
}

当我调用此方法时,我得到以下异常 -

org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance beforeQuery flushing : com.poc.CouponHistory.validityCoupon -> com.poc.Coupon; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance beforeQuery flushing : com.poc.CouponHistory.validityCoupon -> com.poc.Coupon

我不明白为什么当我在单个交易中在父实体之前保存子实体时,hibernate会抱怨我。

如果我将ID生成更改为Auto for Coupon Entity,那么一切都会正常运行。但我想手动分配优惠券代码,因此Id自动生成不在范围内。

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:2)

由于您没有级联优惠券,因此您需要在保存CouponHistory之前对其进行管理,幸运的是,在保存实体时,save()将返回托管持久化实体,因此您只需将其分配给优惠券

 @Transactional
public void createCoupon() {
Coupon coupon = new Coupon();
coupon.setCode(RandomStringUtils.randomAlphanumeric(5));
coupon.setValidity(1);
coupon = couponRepository.save(coupon);//save will return the managed entity

CouponHistory couponHistory = new CouponHistory();
couponHistory.setCreatedOn(new Date());
couponHistory.setCoupon(coupon);
couponHistoryRepository.save(couponHistory);
}

答案 1 :(得分:0)

尝试使用@PersistenceContext连接实体管理器,并在保存this.entityManager.flush()后执行Coupon

Hibernate试图尽可能多地等待持久化实体(通常直到交易结束),你可以强迫'通过明确刷新。