使用@Embeddable和cascade持久保存三个级别时,对INSERTED id进行Hibernate NullPointer

时间:2017-02-14 03:24:08

标签: hibernate jpa cascade embeddable

我无法在最后一个实体中使用@EmbeddedId级联合并持久保存三个级别的实体。我有三个以下实体:
1.凭证
2.率 3. RatePerChannelOverwrite

服务提取Voucher。然后我想在凭证中添加新的Rate。然后我想向RatePerChannelOverwrite添加新的Rate。因此,RateRatePerChannelOverwrite都将@Id设为NULL。这很有效。

但是后来我尝试将RatePerChannelOverwrite分成两个类,并且:@Embeddable RatePerChannelOverwriteId。而这种设置失败了。 Rate所引用的RatePerChannelOverwriteId永远不会填充其新ID。

@Entity
public class Voucher {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Integer id;

    @OneToMany(mappedBy = "voucher", fetch = FetchType.LAZY, orphanRemoval = true, cascade = CascadeType.ALL)
    private Set<Rate> rates = new HashSet<Rate>();
}

@Entity
public class Rate {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Integer id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "voucher_id", referencedColumnName = "id")
    private Voucher voucher;

    @Column(name = "rate", precision = 2, scale = 9, columnDefinition = "decimal")
    @NumberFormat(pattern = "#0.00")
    private double rate;

    @OneToMany(mappedBy = "rate", fetch = FetchType.EAGER, orphanRemoval = true, cascade = CascadeType.ALL)
    private Set<RatePerChannelOverwrite> ratePerChannelOverwrites;
}

@Entity
public class RatePerChannelOverwrite {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "rate_id", referencedColumnName = "id")
    private Rate rate;

    @Column(name = "channel_id")
    private Integer channelId;

    @Column(name = "rate", precision = 2, scale = 9, columnDefinition = "decimal")
    @NumberFormat(pattern = "#0.00")
    private double rate;
}

当我做这样的事情时,这很好用:

Voucher voucher = service.getVoucher(123456); 
Rate rate = new Rate(); //NOTE ID IS NULL HERE
rate.setVoucher(voucher);
voucher.getRates().add(rate);

RatePerChannelOverwrite channelRate = new RatePerChannelOverwrite();
channelRate.setRate(rate);
rate.getRatePerChannelOverwrites.add(channelRate);   

voucher = voucher.merge();

但是当我将最后一个实体分成两个单独的类时,idrate的{​​{1}}总是为空。不知怎的,这里的级联失败了。

注意:第三个实体的复合键为RatePerChannelOverwriteId @EmbeddedId,这就是问题出现的地方。

@ManyToOne

这样做是否正确?

@Embeddable
public class RatePerChannelOverwriteId {
    @ManyToOne
    @JoinColumn(name = "rate_id", referencedColumnName = "id")
    private Rate rate;

    @Column(name = "channel_id")
    private Integer channelId;
}

@Entity
public class RatePerChannelOverwrite {
    @EmbeddedId
    private RatePerChannelOverwriteId id;

    @Column(name = "rate", precision = 2, scale = 9, columnDefinition = "decimal")
    @NumberFormat(pattern = "#0.00")
    private double rate;
}

我得到的实际例外是来自&#39; org.hibernate.type.descriptor.AbstractTypeDescriptor.extractHashCode(T value)&#39;的NullPointer。其中value为NULL,因为Voucher voucher = service.getVoucher(123456); Rate rate = new Rate(); rate.setVoucher(voucher); voucher.getRates().add(rate); RatePerChannelOverwriteId channelRateId = new RatePerChannelOverwriteId(); channelRateId.setRate(rate); RatePerChannelOverwrite channelRate = new RatePerChannelOverwrite(); channelRate.setId(channelRateId); rate.getRatePerChannelOverwrites.add(channelRate); voucher = voucher.merge(); 中的id仍为NULL(尽管SQL跟踪显示INSERT已在Rate上执行)。

0 个答案:

没有答案