2015-09-15 2 views
2

Я пытался реализовать свой собственный метод перехватчиков, используя аннотации (Guice) в Play !. Однако кажется, что эти аннотации будут работать (и, следовательно, перехватывать), если содержащиеся классы создаются Guice (reference). Это подводит меня к вопросу: как @Transactional работает вне классов Controller в Play !? Это, по сути, метод перехватчика, и он отлично работает независимо от того, как создавались классы-классы? Я могу использовать его в своих моделях и классах обслуживания.Как @Transactional работает вне контроллеров в Play! Фреймворк?

+0

К сожалению, @Transactional работает только с действиями контроллера. Любой другой метод, который вы должны обернуть вручную. Этот вопрос может помочь: http://stackoverflow.com/questions/32443032/where-to-place-transactional-annotation-in-play. – Kris

+0

Хм, это совершенно противоречит тому, что я видел. Если я вызываю сервисную процедуру, аннотированную с помощью '@ Transaction', она все равно работает. Означает ли это, что вызов в стеке вызовов, происходящий из любого места в контроллере, может быть аннотирован с помощью '@ Transaction', но любой другой вызывающий, вне контекста контроллера не может? –

+0

Если вы вызываете метод службы изнутри с аннотированным действием @Transactional в контроллере (весь контроллер также может быть аннотирован), тогда он будет работать. Итак, да, если вы вызываете тот же метод обслуживания из другого места, вне вашего аннотированного действия он не будет работать. В документах https://www.playframework.com/documentation/2.4.x/JavaJPA#[email protected] также упоминаются только действия. Это довольно стыдно: Транзакционная аннотация в произвольных методах была бы довольно особенной (это не проблема в Spring Framework). – Kris

ответ

2

@Transactional не работает вне контроллера. Ваш единственный способ заключается в использовании JPA.withTransaction

Пример:

public Promise<Integer> doWork() { 
    return promise(() -> jpaApi.withTransaction(() -> { 
     return JPA.em() 
      .createNativeQuery("DELETE FROM table WHERE id=1") 
      .executeUpdate(); 
    }), dbExecutionContext); 
} 

Или даже без дополнительного контекста исполнения (выполняется в потоке вызывающего абонента):

public Promise<Integer> doWork() { 
    return jpaApi.withTransaction(() -> { 
     return JPA.em() 
       .createNativeQuery("DELETE FROM table WHERE id=1") 
       .executeUpdate(); 
    }); 
} 

Не забудьте придать play.db .jpa.JPAApi.

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