【问题标题】:JPA: Creating an entity whenever another entity is createdJPA:每当创建另一个实体时创建一个实体
【发布时间】:2011-02-28 11:54:29
【问题描述】:

我在 PGSQL DB 上使用 JPA/Hibernate。

我的应用程序中有一个实体,我想在每次持久化第一个实体时持久化另一个实体(不同类型的)。例如,每当创建“ORDER”时,我想立即保留一个空的“ORDER_INVOICE”实体并将其连接到订单。它们位于两个不同的表中。

起初我想为 ORDER 实体编写一个 @PostPersist 函数并将 ORDER_INVOICE 持久保存在其中,但我的问题是我在此上下文中没有实体管理器。

我希望避免记住在每次 ORDER 持久化时都持久化 ORDER_INVOICE。

这是正确的方法吗?如果是这样,我如何让 EM 进入 PostPersist?如果没有,还有什么更好的方法?

【问题讨论】:

  • “创建”是指“持续”吗?
  • 似乎没有标准化的方法可以做到这一点:来自 JPA 1.0 规范:"In general, portable applications should not invoke EntityManager or Query operations, access other entity instances, or modify relationships in a lifecycle callback method."。也许您可以使用@JB Nizet 所说的解决方案。
  • @MRalwasser:谢谢,很高兴知道,JB Nizet 的解决方案确实很有帮助。

标签: jpa


【解决方案1】:

为什么不简单地在主实体的构造函数中创建它,并在关系上设置 cascade=persist?

@Entity
public class Order {

    @OneToMany(mappedBy = "order", cascade=CascadeType.PERSIST)
    private List<Invoice> invoices = new ArrayList<Invoice>();

    public Order() {
        Invoice i = new Invoice();
        i.setOrder(this);
        this.invoices.add(i);
    }

    // ...
}

已编辑:

为避免在每次调用 Order 的构造函数(例如通过 JPA)时创建新发票,您可以使用这种代码:

@Entity
public class Order {

    @OneToMany(mappedBy = "order", cascade=CascadeType.PERSIST)
    private List<Invoice> invoices = new ArrayList<Invoice>();

    /**
     * Constructor called by JPA when an entity is loaded from DB
     */
    protected Order() {
    }

    /**
     * Factory method; which creates an order and its default invoice
     */
    public static Order createOrder() {
        Order o = new Order();
        Invoice i = new Invoice();
        i.setOrder(o);
        o.invoices.add(i);
    }

    // ...
}

如果订单在通过工厂方法实例化后被持久化,那么发票也将被持久化(感谢级联)。如果订单没有被持久化,那么它将在某个时候被垃圾回收,并且它的默认值也会被取消。

【讨论】:

  • 因为订单的每个构造都会自动创建一个新发票,而我希望它只在持久化订单时创建(只执行一次)。此外,在我的情况下,订单不知道/不关心发票(尽管可以更改)。
  • 你可以保护你的默认构造函数。从数据库加载实体时,JPA 引擎仍会调用它。您将添加一个静态工厂方法,该方法将创建订单及其默认发票,就像我的回答一样。
  • 我明白你的意思。所以让我重申一下 - 我将创建一个方法,它将:1)创建一个新订单 2)用所有需要的数据填写订单 3)保留订单 4)创建发票 5)将发票连接到订单 6)坚持发票。这对我来说听起来不错。你是这个意思吗?
  • 我编辑了答案以向您展示我的意思。订单及其发票的持久化不必在工厂方法中完成。如果您保留订单,其发票也会保留,这要归功于级联。
  • 哦,我明白了。谢谢,很有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-05
  • 1970-01-01
  • 1970-01-01
  • 2013-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多