2013-09-02 6 views
1

У меня есть этот метод JPAServiceImpl:JPA настойчивого лицо без упорствовать() инструкция

@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).

Продавец имеет отношения CascadeType.ALL with 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); 
}   

В этом методе я писал слияния и сохраняющиеся инструкции. Это неправильно?

ответ

2

Это работает, ваш объект Seller загружается через диспетчер объектов в той же транзакции. Во время выполнения он будет заменен прокси-объектом. Каждое изменение этого объекта будет автоматически сохраняться в конце транзакции. Вы можете проверить это очень просто: во время выполнения сделайте brakepoint в своем методе 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 Свойство может сохраняться каскадом (зависит от вашего отображения).
+2

+1 Технический термин в jpa lifecyle является «управляемым» объектом – Ralph

+0

@MaksymDemidas Спасибо за объяснение :) Но у меня есть сомнения: вы сказали, что я могу называть 'em.persist()' для экземпляров, которые были созданы с использованием нового ключевого слова. Я использую «Обратная связь обратной связи = новая обратная связь();», а затем «cartLine.setFeedback (обратная связь)»; Если бы я понял, я мог бы удалить 'em.persist (обратную связь)', если я получил CascadeType = PERSIST выше отношения CartLine с обратной связью; я прав? –

+0

Да, вы правы. –

0

Поскольку ваше лицо находится в управляемом состоянии, вам не нужно звонить percist() методу.

Смежные вопросы