Spring存储库自动转换具有不同类类型的实体 [英] Spring repository auto casts entities with different class types
问题描述
我正在使用MongoRepository接口来为不同的实体扩展我的自定义存储库.现在,我面临一个问题,让我们假设一个例子: 我有2个实体:
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;
}
和
@Document(collection = "person")
public class Manager {
private String major;
}
两个存储库:
@Repository
public interface ManagerRepository extends MongoRepository<Manager, String> {}
和
@Repository
public interface EmployeeRepository extends MongoRepository<Employee, String> {}
保存2个模型时一切顺利:
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"
}
但是,当我从一个存储库中执行findAll()时,我得到了2个对象,其中一个弹簧自动将其强制转换为另一个. 如何避免这种自动投射?或者如何指定我需要获得哪个班级?
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?
推荐答案
对于这两个存储库,您都可以使用@Query
批注指定一个MongoDB JSON查询字符串,该字符串将用于代替从方法名称派生的查询(您必须知道解析存储库的方法名称和构建MongoDB查询存在约定).
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).
因此,通过使用@Query
,您可以执行以下操作:
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'});
但是,此代码存在一个小问题.如果更改Manager
的完全限定的类名,则查询将不会抛出RuntimeException
,但将不返回任何内容.在这种情况下,您可以在@Query
中使用通配符.
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());
提供的Manager.class.getName()
将替换?0
通配符,并且您的查询将正确构建.
The provided Manager.class.getName()
will replace the ?0
wildcard and your query will built properly.
Employee
存储库也是如此,区别在于您必须在@Query
的value
属性中提供Employee
的完全限定的类名.
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.
更多信息:
这篇关于Spring存储库自动转换具有不同类类型的实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!