欲哭無淚啊...一下午的時間就這么被浪費了...一個基於spring mvc和spring data jpa的小項目,當我寫完一個controller的測試用例后,一運行卻報空指針,跟了下是一個dao為null.然后看一下這個dao的代碼:
@Component @Transactional public class XXService { private Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private XXDao xxDao; public void add(XX xxl) { logger.debug("進入XXService.add(XX xx)方法"); xxDao.save(xx); //此處報空指針,原因是xxDao為null
}
一開始我都沒認為這個xxDao會是null,以為是參數有問題,然而斷點跟了一下發現不僅參數沒問題,程序整體過程中都沒有任何不對勁的地方,只有運行到這個dao才報錯..因為這個dao是jpa自動實現的,我就想當然的認為可能是參數或是映射問題導致的生成實現的過程中出現問題,不過現在想想,雖然自動實現dao的過程可能失敗,但是不應該報空指針.百度了一圈,看到個關於@Autowired注入失敗的帖子,此時才想到可能是dao注入失敗了,再跟一遍代碼,的確這里dao沒有注入jpa生成的實現,直接就是個null.這我就有點無解了,別又是spring的什么bug或是jar包沖突,這還怎么玩?當年學spring的時候就遇到過各種奇葩問題,寫錯的代碼卻得到正確結果,寫對的代碼卻因為各種原因一直報錯..
雖然有點無解,但是原帖中有人提過要在所有使用dao的地方包括service都需要@Autowired注入,否則就會失效,那么我檢查一下吧,雖然不報希望,因為這段代碼是我們leader寫了一半的時候我接着寫的,犯錯的概率很小的.話雖這么說,但是看到了如下這段代碼:
@RestController @RequestMapping(value = "/xxx/xx") public class XXController { Logger logger = LoggerFactory.getLogger(getClass()); private XXService xxService = new XXService(); ..... }
我當時就倒了...這里忘了注入也就算了,然而還直接new了一個對象,這樣調用service的時候也不報錯...然后dao層注入直接失敗..
這里印證了之前看到的那個帖子中的觀點:必須在所有使用了dao的地方,包括調用它的servcie都要進行@Autowired注入,否則之后的注入就會失敗..