没有persist()指令的JPA持久实体

Posted

技术标签:

【中文标题】没有persist()指令的JPA持久实体【英文标题】:JPA persistent entity without persist() instruction 【发布时间】:2013-09-02 10:32:04 【问题描述】:

我有这个 JPAServiceImpl 方法:

@Override
@Transactional
public void createPageContent(SellerContent content, long userId) 

    Seller s = em.find(Seller.class,userId);
    content.setSeller(s);

    content.setSeller(s);
    s.addContent(content);

它可以工作,但我想知道它是如何工作的,因为没有任何 em.merge(seller)em.persist(content)

Seller 拥有 CascadeType.ALL 与 SellerContent 关系。

如果这是正常行为,您能解释一下吗?我会写em.merge(seller)em.persist(content)。错了吗?

比如我写了这个方法:

@Override
@Transactional
public void createFeedback(CartLine cartLine, String feedbackString) 
    Product product = cartLine.getProduct();

    Feedback feedback = new Feedback();
    feedback.setFeedbackContent(feedbackString);
    feedback.setCartLine(cartLine);
    cartLine.setFeedback(feedback);
    product.getFeedbacks().add(feedback);
    feedback.setProduct(product);

    em.persist(feedback);
    em.merge(cartLine);
    em.merge(product);
        

在这种方法中,我编写了合并和持久化指令。错了吗?

【问题讨论】:

【参考方案1】:

之所以有效,是因为您的 Seller 对象是通过实体管理器在同一事务中加载的。在运行时它将被代理对象替换。此对象的每次更改都将在事务结束时自动持久化。你可以很容易地检查它:在运行时在你的 createPageContent 方法中创建一个刹车点,然后检查 Seller s 变量的实际类型。它将是以下事情所必需的代理:

检测Seller s 状态的每一个变化(例如s.addContent(content))。在事务结束时保留这些更改。 加载惰性关系。想象一下你的SellerOwner 的列表。默认情况下,在运行时此列表将为空。它将在您执行s.getOwners().iterator() 时准确加载。

所以通常您只需要为使用new 关键字创建的实例调用em.persist()。大多数时候,即使这样也没有必要:您可以将新对象A 附加到持久对象B,然后调用em.persist(B)A 将被级联持久化。

第二块代码:

我认为您可以安全地删除em.merge 呼叫。仅当您执行 CartLine mergedCartline = em.merge(cartLine); mergedCartline.doSomething() 时才需要合并。 您可以删除em.persist(feedback) 调用,如果: a) CartLine cartLine 总是通过实体管理器加载; b) cartLine.feedback 属性可以通过级联方式持久化(取决于您的映射)。

【讨论】:

@MaksymDemidas 谢谢你的解释 :) 但我有一个疑问:你说我可以为使用 new 关键字创建的实例调用 em.persist()。我使用Feedback feedback = new Feedback();,然后使用cartLine.setFeedback(feedback);。如果我理解,我可以删除 em.persist(feedback) 如果我得到 CascadeType=PERSIST 以上 CartLine 与反馈的关系;我说的对吗? 完美。谢谢你:)【参考方案2】:

由于您的实体处于托管状态,您不必调用percist() 方法。

【讨论】:

以上是关于没有persist()指令的JPA持久实体的主要内容,如果未能解决你的问题,请参考以下文章

创建没有 persistence.xml 配置文件的 JPA EntityManager

javax.persistence.EntityNotFoundException:已删除的实体传递给持久化

java框架JPA -- JPA基础

netbeans如何通过数据库创建实体类

JPA:HellWord工程

Spring/JPA/persistence 实体属性字段不能是最终的?