在成功验证后,我想调用db以检索一些附加信息,但我得到:
org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
我的successfulAuthentication
方法:
@Override
public void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException, ServletException {
User user = (User) authentication.getPrincipal();
AppUser appUser = userRepo.findByUsername(user.getUsername());
Port port;
portRepo.enableExpiredPorts(LocalDateTime.now());
port = portRepo.checkIfUserHasPort(appUser.getUserId());
if (port == null) {
port = portRepo.getOpenPort();
} else {
portRepo.extendDuration(port.getPort());
}
portRepo.setInUse(appUser.getUserId(), port.getPort());
//Some unrelated logic
}
我正在调用的回购协议:
@Repository
public interface PortRepo extends JpaRepository<Port, Integer> {
@Modifying
@Query(value = "UPDATE Port SET active=1 WHERE expiration<datetime()", nativeQuery = true)
void enableExpiredPorts(@Param("localDateTime")LocalDateTime localDateTime);
@Query(value = "SELECT * FROM Port WHERE user_id=:userId", nativeQuery = true)
Port checkIfUserHasPort(@Param("userId") Long userId);
@Query(value = "SELECT * FROM Port WHERE active=1 LIMIT 1", nativeQuery = true)
Port getOpenPort();
@Modifying
@Query(value = "UPDATE Port SET active=0, user_id=:userId, expiration=datetime('now') WHERE port=:port", nativeQuery = true)
void setInUse(@Param("userId") Long userId, @Param("port") int port);
@Modifying
@Query(value = "UPDATE Port SET expiration=datetime('now') WHERE port=:port", nativeQuery = true)
void extendDuration(@Param("port") int port);
}
添加@Transactional
注解没有帮助(它是来自org.springframework.transaction.annotation.Transactional
的正确注解)
1条答案
按热度按时间1l5u6lss1#
successulAuthentication
是一个内部方法调用,因此添加@Transactional
没有帮助(因为没有通过代理)。最简单的方法是创建另一个类并将逻辑移到那里,然后用
@Transactional
注解该类(或方法)。然后在筛选器中调用此服务,接下来调用super方法。
或者把这一切都抛开,为
InteractiveAuthenticationSuccessEvent
编写一个事件侦听器,然后在那里运行你的逻辑。这样你就不必扩展过滤器等,仍然可以得到想要的行为(并使它松散耦合)。现在,您可以使用侦听器省略修改后的筛选器。