0

Spring Data Jpa と Hibernate の使用に問題があります。

これが私が得る例外です:

2017-05-21 21:42:20.761 DEBUG 11765 --- [nio-8080-exec-5] o.h.e.t.internal.TransactionImpl         : committing
2017-05-21 21:42:20.765  INFO 11765 --- [nio-8080-exec-5] i.StatisticalLoggingSessionEventListener : Session Metrics {
    14574 nanoseconds spent acquiring 1 JDBC connections;
    0 nanoseconds spent releasing 0 JDBC connections;
    55978 nanoseconds spent preparing 2 JDBC statements;
    2315850 nanoseconds spent executing 2 JDBC statements;
    0 nanoseconds spent executing 0 JDBC batches;
    0 nanoseconds spent performing 0 L2C puts;
    0 nanoseconds spent performing 0 L2C hits;
    0 nanoseconds spent performing 0 L2C misses;
    0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
    0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)
}
2017-05-21 21:42:20.779 ERROR 11765 --- [nio-8080-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query] with root cause

javax.persistence.TransactionRequiredException: Executing an update/delete query

AspectJ モードからトランザクション管理を変更した場合

@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)

デフォルトのプロキシ モードへ:

@EnableTransactionManagement

例外は発生しなくなりました。

メソッドの呼び出し順は次のとおりです。

からMessageRestController:

@RestController
...
@PatchMapping("mark-messages-as-read/{otherId}")
public void markMessagesAsRead(@CurrentUserAccount UserAccount me, @PathVariable Long otherId) {
    UserAccount other = userAccountService.findUserAccountById(otherId);
    messageService.markMessagesAsRead(me, other);
}

からMessageService:

@Service
@Transactional
...
@Override
public void markMessagesAsRead(UserAccount me, UserAccount other) {
    Assert.notNull(me);
    Assert.notNull(other);
    messageRepository.markMessagesAsRead(me, other);
}

からMessageRepository:

@Modifying
@Query("update Message m set m.messageRead = true where m.recipient = :me and m.sender= :other")
void markMessagesAsRead(@Param("me") UserAccount me, @Param("other") UserAccount other);

AspectJ モードから Proxy モードに切り替えると例外が発生しなくなる理由を知りたいと非常に興味があります。

誰かアドバイスしてもらえますか?

edit : サービス実装宣言は次のとおりです。

@Service
@Transactional
public class MessageServiceImpl implements MessageService {

そしてサービスインターフェースから:

void markMessagesAsRead(UserAccount me, UserAccount other);
4

1 に答える 1

0

AspectJ の使用に関する公式ドキュメントを読みましたか?

これには AspectJ を使用してアプリケーション コードを作成する必要があります。

もちろん、Spring AOP がクラスのランタイム プロキシを作成しているため、デフォルト設定ではうまく機能します。

于 2017-05-21T20:42:00.863 に答える