Spring mongodb如何使用带有嵌入文档的crudRespository

时间:2014-11-12 22:04:25

标签: schema spring-data-mongodb

为什么当我创建crudRespository来对嵌入对象进行搜索时,没有任何查询工作,并且所有查询都返回null。有什么我做错了吗?有一个例子。 我希望这不是春天mongodb的限制。也许你知道一种不同的方法来提取嵌入对象?我可以使用@DbRef,但我读到它不建议用于性能问题。

Country.class

@Document(collection="countries")
@TypeAlias("ctry")
public class Country {

@Id private BigInteger id;

private String name;

private Continent continent;

public Country(String name, Continent continent) {
    setName(name);
    setContinent(continent);
}
  //get/set omitted 
}

嵌入式文档Continent.class

public final class Continent {

private final long id;
private final String name;

public Continent(long id, String name) {
    this.id = id;
    this.name = name;
}

//get/set omitted 

}

ContinentRespository.class - 这样可以正常返回数据

public interface CountryRepository extends Repository<Country, BigInteger> {

//------------------------------------------- equality

public Country findByName(String countryName);

@Query("{name : ?0}")
public Country findByNameQuery(String countryName);

}

ContinentRespository.class - 所有方法总是返回null:/

public interface ContinentRepository extends CrudRepository<Continent, Long> {

public Continent findByName(String name);

@Query("{name : ?0}")
public Continent findByNameQuery(String name);

 }

RespositoryTest.class - 测试类testFindEmbeddedContinent失败,因为返回的对象为null。 testFindDocumentCountry按预期工作

@ContextConfiguration(classes={MongoConfig.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class RepositoryTest {

@Autowired private CountryRepository countryRepository;
@Autowired private ContinentRepository continentRepo;
@Autowired private MongoOperations mongoOps;
@Autowired private MongoTemplate template;

@Before
public void reset() {
    DBCollection countries = template.getCollection("countries");
    countries.drop();

    countries.insert(dbObjectFromJson("{ '_id' : '8', '_class' : 'ctry', 'name' : 'Japan', 'continent' : { '_id' : 2, 'name' : 'Asia' } }"));
}

@Test
public void testFindEmbeddedContinent() {
    Continent asia = continentRepo.findByName("Asia");
    assertNotNull(asia);
    assertThat(asia.getName(), is(equalTo("Asia")));
}

@Test
public void testFindDocumentCountry() {
    Country japan = countryRepository.findByName("Japan");
    assertNotNull(japan);
    assertThat(japan.getContinent().getName(), is(equalTo("Asia")));
    assertThat(japan.getName(), is(equalTo("Japan")));
}

private static DBObject dbObjectFromJson(String json) {
    return (DBObject) JSON.parse(json);

}
}

1 个答案:

答案 0 :(得分:0)

存储库 - 根据定义 - 模仿聚合根的集合。在MongoDB中,这会转换为集合的顶级文档。因此,您只能为顶级文档创建存储库,例如Country

我不完全确定ContinentCountry的属性(通常是一个国家是大陆的一部分)是有意义的,但这可能仅仅是由于样本。如果您想独立查询Continents,请将它们设为顶级文档,并使用简单ID或DBRef(前者推荐)继续引用该国家。