持久化对象并未持久化其所有关联对象。

huangapple go评论83阅读模式
英文:

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 = &quot;order_id&quot;)
    private long id;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = &quot;customer_id&quot;, nullable = false)
    private Customer customer;

    @OneToMany(mappedBy = &quot;order&quot;)
    private List&lt;Article&gt; orderedArticles;
}

@Entity
@Table
public class Customer implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = &quot;customer_id&quot;)
    private long id;

    @OneToMany(mappedBy = &quot;customer&quot;)
    private List&lt;Order&gt; orders;
}

@Entity
@Table
public class Article implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = &quot;article_id&quot;)
    private long id;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = &quot;order_id&quot;, nullable = false)
    private Order order;
}

And then I persist the order to the database:

Customer customer = createCustomer()
List&lt;Article&gt; 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 = &quot;order&quot;)
private List&lt;Article&gt; orderedArticles;

to

@OneToMany(mappedBy = &quot;order&quot;, cascade = CascadeType.ALL)
private List&lt;Article&gt; orderedArticles;

答案2

得分: 0

  1. 正如在这篇文章中所提到的:

级联在父 - 子关联中才有意义(将实体状态转换级联到其子实体)。从子到父的级联并没有太大用处,通常会引起映射代码上的问题。

因此,例如您的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关联。

  1. 您使用了双向@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关联。


假设您的OrderCustomer实体具有适当的辅助方法,持久化的有效示例如下所示:

  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,所有子实体也将被持久化。

英文:
  1. 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 = &quot;order&quot;, cascade = CascadeType.ALL)
    private List&lt;Article&gt; orderedArticles;
}

@Entity
@Table
public class Article implements Serializable {

    @ManyToOne // CascadeType.ALL should not be used here
    @JoinColumn(name = &quot;order_id&quot;, nullable = false)
    private Order order;
}

The same correction should be made for the Customer - Order association.

  1. 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 = &quot;order&quot;, cascade = CascadeType.ALL)
    private List&lt;Article&gt; 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.

huangapple
  • 本文由 发表于 2020年8月21日 16:57:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/63519700.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定