2017-07-03 7 views
5

बनाता है मैं एक क्षेत्र में आलसी लोड करने के लिए मेरी सेवा पर एक विधि में @Transactional एनोटेशन का उपयोग करने की कोशिश कर रहा हूं। हालांकि, मेरे कार्यान्वयन वर्ग पर @Transactional का उपयोग करके सभी स्वायत्त फ़ील्ड null बनाता है।स्प्रिंग बूट 2 @ ट्रान्सएक्शनल एनोटेशन ऑटोवायर फ़ील्ड शून्य

@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

अपनी विधि से 'अंतिम' निकालें या अपने 'application.properties' में' spring.aop.proxy-target-class = false' सेट करें। ** नोट: ** इसके लिए स्प्रिंग बूट 1.5.3 या पूरी तरह से काम करने की आवश्यकता है! –

+0

क्या आपके वसंत आवेदन में लेनदेन संबंधी संदर्भ सक्षम है? – drgPP

+0

एक लेन-देन करना रीडिंग एक्शन के दौरान बेकार समय है, क्या आपको यकीन है कि आपको रीडिंग-ट्रांजैक्शन की आवश्यकता है? – Zorglube

उत्तर

5

एओपी का उपयोग करके अन्य लोगों के बीच लेनदेन लागू किया जाता है, वसंत में डिफ़ॉल्ट एओपी तंत्र प्रॉक्सी का उपयोग करना है। स्प्रिंग बूट का उपयोग करते समय प्रॉक्सी मोड क्लास आधारित प्रॉक्सी सेट करता है।

आप इसे 2 में से 1 तरीके से ठीक कर सकते हैं।

  1. final अपने विधि से
  2. अक्षम वर्ग आधारित प्रॉक्सी अपने application.properties

को spring.aop.proxy-target-class=false जोड़ने अब जब आप @Transactional aded यह आपके UserServiceImpl के एक प्रॉक्सी के लिए नेतृत्व करेंगे द्वारा एक वर्ग निकालें बनाया जाना, सटीक होने के लिए आधारित प्रॉक्सी। क्या होता है कि आपके UserServiceImpl के लिए उप-वर्ग बनाया गया है और TransactionInterceptor लागू करने के लिए सभी विधियां ओवरराइड हैं। हालांकि आपकी विधि final चिह्नित है क्योंकि गतिशील रूप से बनाई गई कक्षा इस विधि को ओवरराइड नहीं कर सकती है। नतीजतन यह तरीका गतिशील रूप से बनाई गई प्रॉक्सी कक्षा में फ़ील्ड उदाहरणों को देखता है जो हमेशा null होगा।

final हटाते समय विधि को ओवरराइड किया जा सकता है, व्यवहार लागू होता है और यह उचित क्षेत्र के उदाहरणों (प्रॉक्सी के बजाय वास्तविक UserServiceImpl) को देखेगा।

कक्षा आधारित प्रॉक्सी अक्षम करते समय, आपको एक जेडीके डायनामिक प्रॉक्सी मिलेगी जो मूल रूप से एक पतली आवरण है जो आपकी सेवा के सभी इंटरफेस लागू करता है। यह अतिरिक्त व्यवहार (लेनदेन) लागू करता है और वास्तविक सेवा को कॉल करता है। वास्तविक वर्ग की कोई आवश्यकता नहीं है और इस तरह आप अंतिम विधियों को प्रॉक्सी कर सकते हैं (जब तक यह आपके इंटरफ़ेस का हिस्सा हो)।

संबंधित मुद्दे