簡體   English   中英

TransientPropertyValueException:對象引用未保存的瞬態實例 - 在查詢刷新之前保存瞬態實例

[英]TransientPropertyValueException: object references an unsaved transient instance - save the transient instance beforeQuery flushing

我有兩個休眠實體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自動生成不在范圍內。

任何幫助,將不勝感激!

由於您沒有級聯優惠券,因此您需要在保存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);
}

嘗試使用@PersistenceContext實體管理器,並在保存Coupon后執行this.entityManager.flush()

Hibernate試圖盡可能地等待持久化實體(通常直到事務關閉),並且你可以通過顯式刷新來“強迫”它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM