9

Based on the Spring Data Document documentation, I have provided a custom implementation of a repository method. The custom method's name refers to a property which doesn't exist in the domain object:

@Document
public class User {
    String username;
}

public interface UserRepositoryCustom {
    public User findByNonExistentProperty(String arg);
}

public class UserRepositoryCustomImpl implements UserRepositoryCustom {
    @Override
    public User findByNonExistentProperty(String arg) {
        return /*perform query*/;
    }
}

public interface UserRepository
        extends CrudRepository<?, ?>, UserRepositoryCustom {

    public User findByUsername(String username);
}

However, perhaps because of the method name I've chosen (findByNonExistentPropertyName), Spring Data attempts to parse the method name, and create a query from it. When it can't find the nonExistentProperty in User, an exception is thrown.

Possible resolutions:

  1. Have I made a mistake in how I provide the implementation of the custom method?
  2. Is there a way to instruct Spring to not attempt to generate a query based on this method's name?
  3. Do I just have to avoid using any of the prefixes that Spring Data recognizes?
  4. None of the above.

Thank you!

Ryan Tenney
  • 1,812
  • 3
  • 16
  • 29

1 Answers1

11

Your implementation class has to be named UserRepositoryImpl (if you stick to the default configuration) as we try to look it up based on the Spring Data repository interface's name being found. The reason we start with that one is that we cannot reliably know which of the interfaces you extend is the one with the custom implementation. Given a scenario like this

public interface UserRepository extends CrudRepository<User, BigInteger>,
  QueryDslPredicateExecutor<User>, UserRepositoryCustom { … }

we would have to somehow hard code the interfaces not to check for custom implementation classes to prevent accidental pick-ups.

So what we generally suggest is coming up with a naming convention of let's say the Custom suffix for the interface containing the methods to be implemented manually. You can then set up the repository infrastructure to pick up implementation classes using CustomImpl as suffix by using the repository-impl-postfix attribute of the repositories element:

<mongo:repositories base-package="com.acme" 
                    repository-impl-postfix="CustomImpl" />

There's more information on that in the reference documentation but it seems you have at least briefly checked that. :)

Oliver Drotbohm
  • 80,157
  • 18
  • 225
  • 211
  • Thank you very much! I completely missed that the name of implementation in the example didn't contain `Custom`. Since I was implementing `UserRepositoryCustom`, I intuitively expected that Spring Data would look for a class called `UserRepositoryCustomImpl`, but I can appreciate how difficult that may be to implement, without requiring the user to provide additional metadata. Thanks to you and the whole Spring Data team for creating such a fantastic project! – Ryan Tenney Nov 11 '11 at 19:04
  • You're most welcome. We know it would be a bit more intuitive the way you initially thought about it so I am grateful you asked that question as we create some spots of information this way :). – Oliver Drotbohm Nov 11 '11 at 19:25