[英]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
. Code
是CodeImpl
实现的接口。 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
有这个属性,还是CodeImpl
是code
属性的实际类型? 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.