2014-07-04 34 views
1

我正在試驗新的Spring Security測試框架。我有一個測試,涉及返回一個JPA實體與懶惰的集合。Spring集成測試問題涉及一個懶惰集合的實體

由於其中一個懶惰集合,下列測試最終出錯。

@RunWith(SpringJUnit4ClassRunner.class) 
@WebAppConfiguration 
@ActiveProfiles({ Profiles.TEST }) 
@ContextConfiguration(classes = { FullSecurityTestConfiguration.class, FullIntegrationTestConfiguration.class, BaseTestConfiguration.class, WebMvcConfiguration.class, 
     EnableHelperComponents.class }) 
@TestExecutionListeners(listeners = { ServletTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, 
     TransactionalTestExecutionListener.class, WithSecurityContextTestExcecutionListener.class }) 
public class CurriculumPermissionEvaluatorAuthorizationTest { 

    @Autowired 
    private WebApplicationContext wac; 
    private MockMvc mockMvc; 

    @Before 
    public void setup() { 
     mockMvc = MockMvcBuilders.webAppContextSetup(wac).build(); 
    } 

    @After 
    public void clean() { 
     SecurityContextHolder.clearContext(); 
    } 
    @Test 
    @WithUserDetails("[email protected]") 
    public void shouldAllowCurriculumRetrieval() throws Exception { 
     mockMvc.perform(get("/curriculum/findCurriculumById").param("id", "1")// 
       .contentType(MediaType.APPLICATION_JSON)// 
       .header("X-Ajax", "true"))// 
       .andDo(print())// 
       .andExpect(status().isOk());// 
    } 

以下是錯誤消息:

21:40:52.731 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Initiating transaction commit 
21:40:52.732 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Committing JPA transaction on EntityManager [[email protected]] 
21:40:52.733 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Closing JPA EntityManager [[email protected]] after transaction 
21:40:52.733 [main] DEBUG o.s.o.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager 
21:40:52.795 [main] DEBUG o.s.w.s.m.m.a.ResponseBodyAdviceChain - Invoking ResponseBodyAdvice chain for body=Curriculum [drivingLicense=true, smoker=false, maxNumberChildren=2, workExperienceInYears=11, dateOfBirth=1975-01-06 00:00:00.0, telephoneNumber=0142778899, firstName=Juliette, visible=true, validated=true] 
21:40:52.796 [main] DEBUG o.s.w.s.m.m.a.ResponseBodyAdviceChain - After ResponseBodyAdvice chain body=Curriculum [drivingLicense=true, smoker=false, maxNumberChildren=2, workExperienceInYears=11, dateOfBirth=1975-01-06 00:00:00.0, telephoneNumber=0142778899, firstName=Juliette, visible=true, validated=true] 
21:40:52.819 [main] DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolving exception from handler [public com.bignibou.domain.Curriculum com.bignibou.controller.curriculum.CurriculumController.findCurriculumById(java.lang.Long)]: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: com.bignibou.domain.Curriculum.workExperiences, could not initialize proxy - no Session (through reference chain: com.bignibou.domain.Curriculum["workExperiences"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.bignibou.domain.Curriculum.workExperiences, could not initialize proxy - no Session (through reference chain: com.bignibou.domain.Curriculum["workExperiences"]) 
21:40:52.820 [main] DEBUG o.s.w.s.m.a.ResponseStatusExceptionResolver - Resolving exception from handler [public com.bignibou.domain.Curriculum com.bignibou.controller.curriculum.CurriculumController.findCurriculumById(java.lang.Long)]: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: com.bignibou.domain.Curriculum.workExperiences, could not initialize proxy - no Session (through reference chain: com.bignibou.domain.Curriculum["workExperiences"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.bignibou.domain.Curriculum.workExperiences, could not initialize proxy - no Session (through reference chain: com.bignibou.domain.Curriculum["workExperiences"]) 
21:40:52.820 [main] DEBUG o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolving exception from handler [public com.bignibou.domain.Curriculum com.bignibou.controller.curriculum.CurriculumController.findCurriculumById(java.lang.Long)]: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: com.bignibou.domain.Curriculum.workExperiences, could not initialize proxy - no Session (through reference chain: com.bignibou.domain.Curriculum["workExperiences"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.bignibou.domain.Curriculum.workExperiences, could not initialize proxy - no Session (through reference chain: com.bignibou.domain.Curriculum["workExperiences"]) 
21:40:52.821 [main] DEBUG o.s.t.w.s.TestDispatcherServlet - Null ModelAndView returned to DispatcherServlet with name '': assuming HandlerAdapter completed request handling 
21:40:52.821 [main] DEBUG o.s.t.w.s.TestDispatcherServlet - Successfully completed request 

什麼我得到錯誤的,我的測試設置?爲什麼JPA實體經理太早關閉?我怎樣才能繞過這個問題?

編輯1

從控制器方法:

@Override 
    @PreAuthorize("isAuthenticated() AND hasPermission(#curriculumId, 'curriculumByIdOwnerPermission')") 
    @Cacheable(value = CacheConfiguration.DATABASE_CACHE_NAME, key = "'curriculum.Id:' + #curriculumId") 
    public Curriculum findCurriculum(Long curriculumId) { 
     return curriculumRepository.findOne(curriculumId); 
    } 

編輯2

我意識到

@RequestMapping(value = "/findCurriculumById", method = RequestMethod.GET, produces = "application/json") 
    @ResponseBody 
    public Curriculum findCurriculumById(@RequestParam Long id) { 
     return curriculumService.findCurriculum(id); 
    } 

從服務方法測試實際上是錯誤的,即使我已經標註了@Transactional的測試方法如下:

@Test 
@WithUserDetails("[email protected]") 
@Transactional 
public void shouldAllowCurriculumRetrieval() throws Exception { 
    mockMvc.perform(get("/curriculum/findCurriculumById").param("id", "1")// 
      .contentType(MediaType.APPLICATION_JSON)// 
      .header("X-Ajax", "true"))// 
      .andDo(print())// 
      .andExpect(status().isOk());// 
} 

以下是錯誤消息:

16:54:31.747 [main] DEBUG o.s.s.access.vote.AffirmativeBased - Voter: org.springframewor[email protected]ab4a4ae, returned: 1 
16:54:31.747 [main] DEBUG o.s.s.a.i.a.MethodSecurityInterceptor - Authorization successful 
16:54:31.747 [main] DEBUG o.s.s.a.i.a.MethodSecurityInterceptor - RunAsManager did not change Authentication object 
16:54:31.752 [main] DEBUG o.s.w.s.m.m.a.ResponseBodyAdviceChain - Invoking ResponseBodyAdvice chain for body=Curriculum [drivingLicense=true, smoker=false, maxNumberChildren=2, workExperienceInYears=11, dateOfBirth=1975-01-06 00:00:00.0, telephoneNumber=0142778899, firstName=Juliette, visible=true, validated=true] 
16:54:31.752 [main] DEBUG o.s.w.s.m.m.a.ResponseBodyAdviceChain - After ResponseBodyAdvice chain body=Curriculum [drivingLicense=true, smoker=false, maxNumberChildren=2, workExperienceInYears=11, dateOfBirth=1975-01-06 00:00:00.0, telephoneNumber=0142778899, firstName=Juliette, visible=true, validated=true] 
16:54:31.767 [main] DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolving exception from handler [public com.bignibou.domain.Curriculum com.bignibou.controller.curriculum.CurriculumController.findCurriculumById(java.lang.Long)]: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: com.bignibou.domain.Curriculum.workExperiences, could not initialize proxy - no Session (through reference chain: com.bignibou.domain.Curriculum["workExperiences"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.bignibou.domain.Curriculum.workExperiences, could not initialize proxy - no Session (through reference chain: com.bignibou.domain.Curriculum["workExperiences"]) 
16:54:31.768 [main] DEBUG o.s.w.s.m.a.ResponseStatusExceptionResolver - Resolving exception from handler [public com.bignibou.domain.Curriculum com.bignibou.controller.curriculum.CurriculumController.findCurriculumById(java.lang.Long)]: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: com.bignibou.domain.Curriculum.workExperiences, could not initialize proxy - no Session (through reference chain: com.bignibou.domain.Curriculum["workExperiences"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.bignibou.domain.Curriculum.workExperiences, could not initialize proxy - no Session (through reference chain: com.bignibou.domain.Curriculum["workExperiences"]) 
16:54:31.768 [main] DEBUG o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolving exception from handler [public com.bignibou.domain.Curriculum com.bignibou.controller.curriculum.CurriculumController.findCurriculumById(java.lang.Long)]: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: com.bignibou.domain.Curriculum.workExperiences, could not initialize proxy - no Session (through reference chain: com.bignibou.domain.Curriculum["workExperiences"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.bignibou.domain.Curriculum.workExperiences, could not initialize proxy - no Session (through reference chain: com.bignibou.domain.Curriculum["workExperiences"]) 
16:54:31.768 [main] DEBUG o.s.t.w.s.TestDispatcherServlet - Null ModelAndView returned to DispatcherServlet with name '': assuming HandlerAdapter completed request handling 
16:54:31.768 [main] DEBUG o.s.t.w.s.TestDispatcherServlet - Successfully completed request 

MockHttpServletRequest: 
     HTTP Method = GET 
     Request URI = /curriculum/findCurriculumById 
      Parameters = {id=[1]} 
      Headers = {Content-Type=[application/json], X-Ajax=[true]} 

      Handler: 
       Type = com.bignibou.controller.curriculum.CurriculumController 
       Method = public com.bignibou.domain.Curriculum com.bignibou.controller.curriculum.CurriculumController.findCurriculumById(java.lang.Long) 

       Async: 
    Was async started = false 
     Async result = null 

    Resolved Exception: 
       Type = org.springframework.http.converter.HttpMessageNotWritableException 

     ModelAndView: 
      View name = null 
       View = null 
       Model = null 

      FlashMap: 

MockHttpServletResponse: 
       Status = 500 
     Error message = null 
      Headers = {Content-Type=[application/json]} 
     Content type = application/json 
       Body = 
     Forwarded URL = null 
     Redirected URL = null 
      Cookies = [] 
16:54:31.770 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Initiating transaction rollback 
16:54:31.770 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Rolling back JPA transaction on EntityManager [[email protected]] 
16:54:31.771 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Closing JPA EntityManager [[email protected]] after transaction 
16:54:31.771 [main] DEBUG o.s.o.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager 
16:54:31.771 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Resuming suspended transaction after completion of inner transaction 
16:54:31.771 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Creating new transaction with name [com.bignibouX.tests.security.curriculum.CurriculumPermissionEvaluatorAuthorizationTest.clean]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 
16:54:31.771 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Opened new EntityManager [[email protected]] for JPA transaction 
16:54:31.771 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Exposing JPA transaction as JDBC transaction [org.springframewo[email protected]21bcecc5] 
16:54:31.771 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Initiating transaction commit 
16:54:31.772 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Committing JPA transaction on EntityManager [[email protected]] 
16:54:31.772 [main] DEBUG o.s.orm.jpa.JpaTransactionManager - Closing JPA EntityManager [[email protected]] after transaction 

編輯3

這裏是課程的有關部分:

@Entity 
public class Curriculum { 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "curriculum") 
    private Set<WorkExperience> workExperiences; 

回答

0

您的測試方法是而不是交易。

您需要註釋CurriculumPermissionEvaluatorAuthorizationTestshouldAllowCurriculumRetrieval()@Transactional

+0

Sam:我很抱歉:我剛剛意識到用@Transactional註釋該方法實際上並沒有解決問題......我的錯誤是將答案標記爲首先被接受...... – balteo

+0

我編輯過我的帖子有更多的信息。 – balteo

+0

「curriculumService.findCurriculum(id)」的交易配置是什麼樣的?方法,類或接口是否用'@Transactional'註解,如果是的話,那麼'propagation'設置爲什麼? –