2017-07-03 45 views
5

我試圖在我的服務的方法中使用@Transactional註釋來延遲加載字段。然而,在我的Implementation類中使用@Transactional將使所有自動裝配字段nullSpring引導2 @Transactional註釋使得Autowired字段爲空

這是我實現:

@Service 
public class UserServiceImpl implements UserService { 

/** 
    * DefaultMapper. 
    */ 
@Autowired 
private DefaultMapper defaultMapper; 

/** 
    * Resource service injection. 
    */ 
@Autowired 
private ResourceService resourceService; 

/** 
    * UserRepository. 
    */ 
@Autowired 
private UserRepository userRepository; 

/** 
    * Jwt Factory. 
    */ 
@Autowired 
private JwtService jwtService; 

@Override 
@Transactional 
public final UserDto findByLogin(final String login) throws ResourceNotFoundException { 
// user repository is null here when using @Transactional 
    User user = this.userRepository.findByLogin(login) 
    .orElseThrow(() -> new ResourceNotFoundException(
    resourceService.getMessage(MessageBundle.EXCEPTION, "resource.notfound.user.login") 
    )); 
    UserDto userDto = defaultMapper.asUserDtoWithRoles(user); 
    return userDto; 
} 

預先感謝您。

+3

從你的方法中刪除'final'或者在'application.properties'中設置'spring.aop.proxy-target-class = false'。 **注意:**這需要Spring Boot 1.5.3或完全正常工作! –

+0

在你的spring應用程序中啓用了事務上下文嗎? – drgPP

+0

在閱讀行爲中,大部分時間進行交易是無用的,你確定你需要閱讀交易嗎? – Zorglube

回答

5

使用AOP應用事務等,Spring中的默認AOP機制是使用代理。當使用Spring Boot時,代理模式被設置爲基於類的代理。

您可以通過2種方法之一解決此問題。

  1. 加入spring.aop.proxy-target-class=falseapplication.properties

現在,當您交鋒@Transactional這將導致你的UserServiceImpl的代理從你的方法刪除final

  • 禁用基於類的代理被創建,一類基於代理的準確。會發生什麼是爲您的UserServiceImpl創建了一個子類,並且覆蓋了所有方法以應用TransactionInterceptor。但是,由於您的方法被標記爲final,動態創建的類不能重寫此方法。因此,該方法將查看動態創建的代理類中的字段實例,該代理類始終爲null

    當刪除final該方法可以被覆蓋,應用的行爲,它會查看適當的字段實例(實際UserServiceImpl而不是代理)。

    禁用基於類的代理時,您將獲得一個JDK動態代理,它基本上是一個實現您的服務實現的所有接口的薄包裝器。它應用添加的行爲(事務)並調用實際的服務。沒有實際類所需的擴展,因此您可以代理最終方法(只要它是您的接口的一部分)。

  • 相關問題