1

我有这个 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)or em.persist(content)

卖家有 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);
}        

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

4

2 回答 2

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属性可以通过级联进行持久化(取决于您的映射)。
于 2013-09-02T12:20:41.013 回答
0

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

于 2013-11-29T20:56:04.083 回答