Hibernate @OneToMany 关联尝试设置空 FK 值
Hibernate @OneToMany association tries to set a null FK value
我有以下简单示例。当它运行时,我看到使用自动生成的 ID 生成的 QuoteRequest 对象。接下来,我看到正在生成 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);
When creating Accidents, I don't set the quoteRequest property. Should I be doing anything with that? Do I need to have a bi-directional relationship?
就是这个原因。
首先,"Do I need to have a bi-directional relationship?"。好吧,你是唯一知道的人。但是,您已经拥有双向关系。顺便说一句,Accident
方拥有这种关系。这意味着,对于数据库列 Accident.quote_req_id
依赖于字段 Accident.quoteRequest
。由于您尚未填充该字段,Hibernate 假设它为空。因此它正在插入空值。所有预期行为。
总之,要确保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
现在被另一个列表替换)
我有以下简单示例。当它运行时,我看到使用自动生成的 ID 生成的 QuoteRequest 对象。接下来,我看到正在生成 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);
When creating Accidents, I don't set the quoteRequest property. Should I be doing anything with that? Do I need to have a bi-directional relationship?
就是这个原因。
首先,"Do I need to have a bi-directional relationship?"。好吧,你是唯一知道的人。但是,您已经拥有双向关系。顺便说一句,Accident
方拥有这种关系。这意味着,对于数据库列 Accident.quote_req_id
依赖于字段 Accident.quoteRequest
。由于您尚未填充该字段,Hibernate 假设它为空。因此它正在插入空值。所有预期行为。
总之,要确保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
现在被另一个列表替换)