Hibernate @OneToMany关联试图设置一个空的FK值



我有以下简单的例子。当它运行时,我看到QuoteRequest对象以自动生成的id生成。接下来,我看到生成了Accidents对象,但是插入的quote_request_id为空,因此我得到了一个错误:

专栏"quote_request_id"不能空

@Entity
@Table(name = "Quotes")
public class QuoteRequest
{
    public QuoteRequest(){}
    @Id
    @Column(name = "quote_request_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long QuoteRequestId;

    @OneToMany(mappedBy = "quoteRequest", cascade = CascadeType.ALL)
    @OrderColumn(name = "accidents_id")
    private Accidents[] accidents;
    // Getters and setters
}
@Entity
@Table(name = "Accidents")
public class Accidents
{
    public Accidents()
    {
    }
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "accidents_id")
    private long AccidentId;

    @Column(name = "amount", nullable = false)
    private Float amount;
    @ManyToOne(optional = false, cascade = CascadeType.ALL)
    @JoinColumn(name = "quote_request_id", nullable = false)
    private QuoteRequest quoteRequest;
    // Getters and setters
}

为什么不将新生成的ID插入事故列?

首先,将@OneToMany从使用数组改为使用List:

@OneToMany(mappedBy = "quoteRequest", cascade = CascadeType.ALL)
@OrderColumn(name = "accidents_id")
private List<Accidents> accidents = new ArrayList()<>;

确保设置了关联的两边:

QuoteRequest quoteRequest = ...
Accidents accidents = ...
quoteRequest.getAccidents().add(accident);
accident.setQuoteRequest(quoteRequest);

当创建事故时,我没有设置quoteRequest属性。我该拿它做点什么吗?我需要一个双向的关系吗?

这就是原因。

首先,"我需要一个双向关系吗?"你是唯一知道的人。然而,你已经有了双向的关系。通过你设置的方式,Accident方拥有关系。这意味着,对于DB列Accident.quote_req_id依赖于字段Accident.quoteRequest。由于没有填充该字段,Hibernate假定该字段为空。因此它插入null。所有预期行为

简而言之,您应该确保QuoteRequest.accidentAccident.quoteRequest是一致的,例如:

class QuoteRequest {
    private List<Accident> accidents = new ArrayList<>();  // I prefer List or Set
    public void setAccidents(List<Accident> accidents) {
        this.accidents.clear();
        if (accidents != null) {
            // intentionally keeping another list, to be defensive and not
            // affected by subsequent change in the caller's list
            this.accidents = this.accidents.addAll(accidents);
            for (Accident accident:accidents) {
                accident.setQuoteRequest(this);
            }
        }
    }
}
class Accident {
    private QuoteRequest quoteRequest;
    public setQuoteRequest(QuoteRequest quoteRequest) {
        // there will be something more...
        this.quoteRequest = quoteRequest;
    }
}

这只是一个非常基本的例子。简而言之,您需要将Accident.quoteRequest设置为合适的值。在上述实现中仍然存在很多问题,我会把它留给你(例如,当你以前有accidents设置,现在用另一个列表替换)

最新更新