Issue
I have the following simple example. When it runs, I see the QuoteRequest object being generated with auto-generated id. Next, I see the Accidents object being generated, but quote_request_id that's being inserted is null, so I get an error:
Column 'quote_request_id' cannot be null
@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
}
Why isn't it inserting the newly generated ID into the accidents column?
Solution
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?
This is the reason.
First, "Do I need to have a bi-directional relationship?". Well, you are the only one that can tell. However, you are already having bi-directional relationship. By the way you set that up, Accident
side is owning the relationship. That means, for the DB Column Accident.quote_req_id
is relying on the field Accident.quoteRequest
. As you have not populate that field, Hibernate is assuming that is a null. Hence it is inserting null. All expected behavior.
In short, you should make sure QuoteRequest.accident
and Accident.quoteRequest
is consistent, for example:
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;
}
}
This is just a very basic example on what it will look like. In short, you need Accident.quoteRequest
set with appropriate value. There are still lots of issue in above implementation and I will leave it for you (e.g. when you previously has accidents
set and now replaced with another list)
Answered By - Adrian Shum
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.