Reputation: 369
I'm using MongoRepository interface to extend my custom repositories for different entities. Now I faced with problem, let's assume an example: I have 2 entities:
@Document(collection = "person")
public class Employee {
private String position;
}
and
@Document(collection = "person")
public class Manager {
private String major;
}
repositories for both:
@Repository
public interface ManagerRepository extends MongoRepository<Manager, String> {}
and
@Repository
public interface EmployeeRepository extends MongoRepository<Employee, String> {}
Everything goes well when I saving 2 models:
{
"_id" : ObjectId("5541f988d4c603ebac18a147"),
"_class" : "com.igmtechnology.gravity.core.init.test.Manager",
"major" : "majority"
}
{
"_id" : ObjectId("5541f988d4c603ebac18a148"),
"_class" : "com.igmtechnology.gravity.core.init.test.Employee",
"position" : "developer"
}
But when I'm doing findAll() from one of repositories I'm getting 2 objects and one of them spring is automatically casting to another one. How can avoid this auto casting? Or how can specify which class I need to get?
Upvotes: 7
Views: 2891
Reputation: 62854
For both of the repositories, you can use the @Query
annotation to specify a MongoDB JSON query string that will be used instead of query derived from the method's name (you must know that there's a convention for parsing the repository's method names and for building MongoDB queries).
So, by using @Query
, you can do:
@Repository
public interface ManagerRepository extends MongoRepository<Employee, String>
@Query(value="{ '_class' : 'com.igmtechnology.gravity.core.init.test.Manager' }")
List<Person> findAllManagers();
}
Behind the scenes, this will generate a query, similar to this one:
db.person.findAll({'_class' ; 'com.igmtechnology.gravity.core.init.test.Manager'});
However, there's a minor problem with this code. If you change the fully-qualified class name of Manager
, then the query would not throw a RuntimeException
, but would return nothing. In this case you can use a wildcard within the @Query
.
@Query(value="{ '_class' : ?0 }")
List<Person> findAllManagers(String className);
Then, when you invoke the method, you can just do:
managerRepository.findAllManagers(Manager.class.getName());
The provided Manager.class.getName()
will replace the ?0
wildcard and your query will built properly.
Same goes for the Employee
repository with the difference that you have to provide the fully-qualified class name of Employee
in the @Query
's value
attribute.
More info:
Upvotes: 7