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

时间:2013-09-02 10:32:04

标签: java spring jpa orm

我有这个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)

卖家已获得具有SellerContent关系的CascadeType.ALL。

如果这是正常的行为,请你解释一下吗?我会写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);
}        

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

2 个答案:

答案 0 :(得分:2)

它是有效的,因为您的Seller对象是通过同一事务中的实体管理器加载的。在运行时,它将被代理对象替换。对象的每次更改都将在事务结束时自动保留。您可以非常轻松地检查它:在运行时使用createPageContent方法制作制动点,然后检查Seller s变量的实际类型。它将成为跟踪事物所必需的代理:

  • 检测Seller s州的所有更改(例如s.addContent(content))。在交易结束时坚持这些变化。
  • 加载懒惰关系。假设您的Seller包含Owner列表。默认情况下,在运行时此列表将为空。它将在您执行s.getOwners().iterator()时完全加载。

通常,您只需要为使用em.persist()关键字创建的实例调用new。大部分时间甚至不需要这样做:您可以将新对象A附加到持久对象B,然后调用em.persist(B)A将由级联保留。

代码的第二块:

  • 我认为您可以安全地删除em.merge来电。执行CartLine mergedCartline = em.merge(cartLine); mergedCartline.doSomething()时仅合并必要。
  • 如果出现以下情况,您可以删除em.persist(feedback)来电:a)CartLine cartLine始终通过实体经理加载; b)cartLine.feedback属性可以通过级联持久化(取决于您的映射)。

答案 1 :(得分:0)

由于您的实体处于托管状态,因此您无需调用percist()方法。