我有以下简单的例子。当它运行时,我看到正在使用自动生成的ID生成QuoteRequest对象。接下来,我看到正在生成Accidents对象,但是要插入的quote_request_id为null,因此出现错误:
列“ 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插入事故列?
最佳答案
创建事故时,我没有设置quoteRequest属性。我应该做些什么吗?我需要建立双向关系吗?
这就是原因。
首先,“我需要建立双向关系吗?”。好吧,你是唯一可以说出来的人。但是,您已经具有双向关系。通过设置的方式,Accident
一方拥有该关系。这意味着,对于DB列Accident.quote_req_id
依赖于字段Accident.quoteRequest
。由于您尚未填充该字段,因此Hibernate假定该字段为null。因此,它正在插入null。所有预期的行为。
简而言之,应确保QuoteRequest.accident
和Accident.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
并现在被另一个列表替换时)