我有两个休眠实体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自动生成不在范围内。
任何帮助将不胜感激!
答案 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试图尽可能多地等待持久化实体(通常直到交易结束),你可以强迫'通过明确刷新。