I'm encountering an error with a Spring Data repository as it attempts to resolve a property expression:
public interface ContractRepository
extends MongoRepository<Contract,String> {
public List<Contract> findByCodeBindings(String binding);
}
Here's the relevant parts of 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
. It contains a property bindings
, which has a getter and setter in Code
. 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:
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
. However, because Code
is an interface, it has no properties listed.
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? I'm surprised that the library doesn't attempt to parse the getters or setters of the interface.
This is using spring-data-commons 1.5.1.RELEASE and 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:And
PersistentContract
was implemented in terms of concrete classes:This seems to strike the right balance between coding against interfaces in the base class and satisfying Spring Data's need for concrete classes.