Reputation:
I am have three entities with relations look like this:
Here are my Java Classes:
@Entity
@Table
public class Order implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "order_id")
private long id;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "customer_id", nullable = false)
private Customer customer;
@OneToMany(mappedBy = "order")
private List<Article> orderedArticles;
}
@Entity
@Table
public class Customer implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "customer_id")
private long id;
@OneToMany(mappedBy = "customer")
private List<Order> orders;
}
@Entity
@Table
public class Article implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "article_id")
private long id;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "order_id", nullable = false)
private Order order;
}
And then I persist the order to the database:
Customer customer = createCustomer()
List<Article> articles = createArticles();
Order order = new Order(customer, articles)
entityManager.persist(order);
The order and customer were successfully persisted but strangely that the article not. Can anyone help me here what did i do wrong? How can I make one call to persist the order and parallel the customer and article will be also persisted?
Thank you very much!
Upvotes: 0
Views: 65
Reputation: 13111
Cascading only makes sense for Parent – Child associations (the Parent entity state transition being cascaded to its Child entities). Cascading from Child to Parent is not very useful and usually, it’s a mapping code smell.
So, for example your Order - Article association should be corrected in this way:
@Entity
@Table
public class Order implements Serializable {
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<Article> orderedArticles;
}
@Entity
@Table
public class Article implements Serializable {
@ManyToOne // CascadeType.ALL should not be used here
@JoinColumn(name = "order_id", nullable = false)
private Order order;
}
The same correction should be made for the Customer - Order association.
@OneToMany
. So, as documentation states:Whenever a bidirectional association is formed, the application developer must make sure both sides are in-sync at all times.
For example your Order
entity should have the following methods:
@Entity
@Table
public class Order implements Serializable {
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<Article> orderedArticles;
public void addArticle(Article article) {
orderedArticles.add(article);
article.setOrder(this);
}
public void removeArticle(Article article) {
orderedArticles.remove(article);
article.setOrder(null);
}
}
to make the bidirectional association Order - Article in-sync. The same correction should be made for the Customer - Order association.
Assuming that your Order
and Customer
entities have the appropriate helper methods, the valid example of persisting can look like this:
Article article1 = new Article();
// ...
Article article2 = new Article();
// ...
Order order = new Order();
order.addArticle(article1);
order.addArticle(article2);
Customer customer = new Customer();
customer.addOrder(order);
entityManager.persist(customer);
So, you should start from articles creation, then add them to the order (or orders), then add your order (or orders) to the customer entity and then persist
the customer. Due to the usage of CascadeType.ALL
all children entities will be persisted too.
Upvotes: 0
Reputation: 13
Try change
@OneToMany(mappedBy = "order")
private List<Article> orderedArticles;
to
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<Article> orderedArticles;
Upvotes: 1