英文:
Persisting object does not persist all its relational objects
问题
以下是您提供的内容的翻译:
我有三个实体及其关系如下:
- Customer(客户)和Order(订单):一对多
- Order(订单)和Article(文章):一对多
以下是我的Java类:
@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;
}
然后,我将订单持久化到数据库:
Customer customer = createCustomer();
List<Article> articles = createArticles();
Order order = new Order(customer, articles);
entityManager.persist(order);
订单和客户已成功持久化,但奇怪的是文章没有。有人可以帮助我,指出我做错了什么吗?我如何在一次调用中持久化订单,并且同时客户和文章也会被持久化?
非常感谢!
英文:
I am have three entities with relations look like this:
- Customer and Order: one-to-many
- Order and Article: one-to-many
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!
答案1
得分: 1
尝试更改
@OneToMany(mappedBy = "order")
private List<Article> orderedArticles;
为
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<Article> orderedArticles;
英文:
Try change
@OneToMany(mappedBy = "order")
private List<Article> orderedArticles;
to
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<Article> orderedArticles;
答案2
得分: 0
- 正如在这篇文章中所提到的:
级联在父 - 子关联中才有意义(将父实体状态转换级联到其子实体)。从子到父的级联并没有太大用处,通常会引起映射代码上的问题。
因此,例如您的Order - Article关联应该进行以下更正:
@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
@JoinColumn(name = "order_id", nullable = false)
private Order order;
}
同样的更正也应该应用于Customer - Order关联。
- 您使用了双向
@OneToMany
。正如文档中所述:
当形成双向关联时,应用程序开发人员必须确保双方始终保持同步。
例如,您的Order
实体应该有以下方法:
@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);
}
}
以使双向关联Order - Article保持同步。同样的更正也应该应用于Customer - Order关联。
假设您的Order
和Customer
实体具有适当的辅助方法,持久化的有效示例如下所示:
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);
因此,您应该从创建文章开始,然后将它们添加到订单(或订单),再将订单(或订单)添加到客户实体中,然后对客户进行persist
操作。由于使用了CascadeType.ALL
,所有子实体也将被持久化。
英文:
- As it mentioned in this article:
> 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.
- You use bidirectional
@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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论