“PersistentEntity不能为null”MongoDB和Spring Data REST的异常

时间:2017-03-15 13:28:49

标签: java mongodb junit spring-data spring-data-rest

使用Spring Data REST和MongoDB创建项目的每次尝试都遇到了同样烦人的问题。尝试访问REST端点的每个测试都会导致java.lang.IllegalArgumentException: PersistentEntity must not be null!PersistentEntityResource构建器方法引发。这意味着当应用程序上下文启动并初始化RepositoryRestMvcConfiguration时,PersistentEntities bean为空。一些示例代码:

@Document
public class Person {
    @Id private String id;
    private String name;
    private Integer age;
    // Getters and setters
}

@RepositoryRestResource(path = "persons", collectionResourceRel = "persons")
public interface PersonRepository extends MongoRepository<Person, String> {
}

@Configuration
@EnableMongoRepositories(basePackages = { "me.woemler.test" })
public class DataSourceConfig {

   @Bean(destroyMethod = "close")
   public Mongo mongo() throws IOException {
     return new EmbeddedMongoBuilder().build();
   }

   @Bean
   public MongoTemplate mongoTemplate(Mongo mongo){
     return new MongoTemplate(mongo, "test-db");
   }

 }

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = {DataSourceConfig.class, RepositoryRestMvcConfiguration.class})
public class PersonTests {

  @Autowired private PersonRepository personRepository;
  @Autowired private WebApplicationContext context;
  private MockMvc mockMvc;

  @Before
  public void setup(){
    personRepository.deleteAll();
    Person person = new Person();
    person.setName("Joe");
    person.setAge(33);
    personRepository.save(person);
    mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
  }

  @Test
  public void test() throws Exception{
      mockMvc.perform(MockMvcRequestBuilders.get("/persons"))
        .andExpect(MockMvcResultMatchers.status().isOk());
  }

}

Stacktrace是:

Caused by: java.lang.IllegalArgumentException: PersistentEntity must not be null!
    at org.springframework.util.Assert.notNull(Assert.java:134)
    at org.springframework.data.rest.webmvc.PersistentEntityResource$Builder.<init>(PersistentEntityResource.java:140)
    at org.springframework.data.rest.webmvc.PersistentEntityResource$Builder.<init>(PersistentEntityResource.java:123)
    at org.springframework.data.rest.webmvc.PersistentEntityResource.build(PersistentEntityResource.java:115)
    at org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler.wrap(PersistentEntityResourceAssembler.java:74)
    at org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler.toResource(PersistentEntityResourceAssembler.java:55)
    at org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler.toResource(PersistentEntityResourceAssembler.java:38)
    at org.springframework.data.web.PagedResourcesAssembler.createResource(PagedResourcesAssembler.java:200)
    at org.springframework.data.web.PagedResourcesAssembler.toResource(PagedResourcesAssembler.java:132)
    at org.springframework.data.rest.webmvc.AbstractRepositoryRestController.entitiesToResources(AbstractRepositoryRestController.java:92)
    at org.springframework.data.rest.webmvc.AbstractRepositoryRestController.toResources(AbstractRepositoryRestController.java:76)
    at org.springframework.data.rest.webmvc.RepositoryEntityController.getCollectionResource(RepositoryEntityController.java:209)

我使用Spring Boot,Spring Data MongoDB和Spring Data REST以及最新的Spring Platform版本(Brussels-SR1)。使用Spring Boot运行应用程序时,我没有收到任何错误,只有在使用SpringJUnit4ClassRunnerSpringRunner进行测试时才会收到错误。我错过了什么?

1 个答案:

答案 0 :(得分:2)

有同样的问题,不得不经常调试spring internals

错误的原因 - 在MongoTemplate中缺少MappingConverter对象。 当使用构造函数时,Spring自动创建mongoTemplate bean

public MongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter mongoConverter) 

要解决此问题,有两种选择:

1)不要重新定义MongoTemplate bean。您可以使用application.properties指定数据库

spring.data.mongodb.uri=mongodb://hostname:27017/dbName

2)自动装配mongoConverter并用于创建mongoTemplate

@Autowired
private MongoConverter mongoConverter;

public @Bean
MongoTemplate mongoTemplate() throws Exception {
    MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), mongoConverter);
    return mongoTemplate;
}

希望这有帮助