简体   繁体   English

使用Spring Data和MongoDB解析子文档类型

[英]Resolving subdocument types with Spring Data and MongoDB

I'm encountering an error with a Spring Data repository as it attempts to resolve a property expression: 我在尝试解析属性表达式时遇到Spring Data存储库的错误:

public interface ContractRepository
    extends MongoRepository<Contract,String> {
    public List<Contract> findByCodeBindings(String binding);
}

Here's the relevant parts of Contract : 这是Contract的相关部分:

@Document(collection="CONTRACTS")
public class PersistentContract extends BaseContract {
    @PersistenceConstructor
    public PersistentContract(String name, Version version, Code code) {
        super(name, version, code);
    }
}

Code is an interface implemented by CodeImpl . CodeCodeImpl实现的接口。 It contains a property bindings , which has a getter and setter in Code . 它包含一个属性bindings ,它在Code有一个getter和setter。 So the query's property expression is designed to find those contracts with a nested Code document containing a given binding. 因此,查询的属性表达式旨在使用包含给定绑定的嵌套代码文档来查找这些契约。 So far, so good. 到现在为止还挺好。

However, the problem is an IllegalArgumentException is getting thrown: 但是,问题是抛出了IllegalArgumentException

java.lang.IllegalArgumentException: No property bindings found on my.company.Code!
 org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:225)

Debugging that section of code shows that Spring Data is picking apart the expression and determines there's a property of type Code . 调试该部分代码显示Spring Data正在分离表达式并确定存在Code类型的属性。 However, because Code is an interface, it has no properties listed. 但是,由于Code是一个接口,因此没有列出任何属性。

Is there a means to hint to Spring Data that either Code has this property or that CodeImpl is the actual type of the code property? 有没有办法提示Spring Data, Code有这个属性,还是CodeImplcode属性的实际类型? I'm surprised that the library doesn't attempt to parse the getters or setters of the interface. 我很惊讶该库不会尝试解析接口的getter或setter。

This is using spring-data-commons 1.5.1.RELEASE and spring-data-mongodb 1.2.1.RELEASE. 这是使用spring-data-commons 1.5.1.RELEASE和spring-data-mongodb 1.2.1.RELEASE。

Appreciate the help. 感谢帮助。

My solution was to avoid interfaces at all in the persistent object. 我的解决方案是避免持久对象中的接口。 So BaseContract became the following: 所以BaseContract成为以下内容:

public abstract class BaseContract<T extends Code> {
    public abstract T getCode();
}

And PersistentContract was implemented in terms of concrete classes: PersistentContract是根据具体类实现的:

public class PersistentContract extends BaseContract<CodeImpl> {
}

This seems to strike the right balance between coding against interfaces in the base class and satisfying Spring Data's need for concrete classes. 这似乎在编写基类中的接口和满足Spring Data对具体类的需求之间取得了适当的平衡。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM