Spring 存储库自动转换具有不同 class 类型的实体
Spring repository auto casts entities with different class types
我正在使用 MongoRepository 接口为不同的实体扩展我的自定义存储库。现在我遇到了问题,让我们假设一个例子:
我有 2 个实体:
@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 个模型时一切顺利:
{
"_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 个对象,其中一个 spring 会自动转换为另一个对象。
如何避免这种自动铸造?或者如何指定我需要得到哪个 class?
对于这两个存储库,您可以使用 @Query
注释来指定将使用的 MongoDB JSON 查询字符串,而不是从方法名称派生的查询(您必须知道有一个解析存储库方法名称和构建 MongoDB 查询的约定)。
因此,通过使用 @Query
,您可以:
@Repository
public interface ManagerRepository extends MongoRepository<Employee, String>
@Query(value="{ '_class' : 'com.igmtechnology.gravity.core.init.test.Manager' }")
List<Person> findAllManagers();
}
在幕后,这将生成一个查询,与此类似:
db.person.findAll({'_class' ; 'com.igmtechnology.gravity.core.init.test.Manager'});
但是,这段代码有一个小问题。如果更改 Manager
的完全限定 class 名称,则查询不会抛出 RuntimeException
,但 return 什么也不会抛出。在这种情况下,您可以在 @Query
.
中使用通配符
@Query(value="{ '_class' : ?0 }")
List<Person> findAllManagers(String className);
然后,当你调用该方法时,你可以这样做:
managerRepository.findAllManagers(Manager.class.getName());
提供的 Manager.class.getName()
将替换 ?0
通配符,您的查询将正确构建。
Employee
存储库也是如此,不同之处在于您必须在 @Query
的 [=] 中提供 Employee
的完全限定 class 名称24=]属性。
更多信息:
我正在使用 MongoRepository 接口为不同的实体扩展我的自定义存储库。现在我遇到了问题,让我们假设一个例子: 我有 2 个实体:
@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 个模型时一切顺利:
{
"_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 个对象,其中一个 spring 会自动转换为另一个对象。 如何避免这种自动铸造?或者如何指定我需要得到哪个 class?
对于这两个存储库,您可以使用 @Query
注释来指定将使用的 MongoDB JSON 查询字符串,而不是从方法名称派生的查询(您必须知道有一个解析存储库方法名称和构建 MongoDB 查询的约定)。
因此,通过使用 @Query
,您可以:
@Repository
public interface ManagerRepository extends MongoRepository<Employee, String>
@Query(value="{ '_class' : 'com.igmtechnology.gravity.core.init.test.Manager' }")
List<Person> findAllManagers();
}
在幕后,这将生成一个查询,与此类似:
db.person.findAll({'_class' ; 'com.igmtechnology.gravity.core.init.test.Manager'});
但是,这段代码有一个小问题。如果更改 Manager
的完全限定 class 名称,则查询不会抛出 RuntimeException
,但 return 什么也不会抛出。在这种情况下,您可以在 @Query
.
@Query(value="{ '_class' : ?0 }")
List<Person> findAllManagers(String className);
然后,当你调用该方法时,你可以这样做:
managerRepository.findAllManagers(Manager.class.getName());
提供的 Manager.class.getName()
将替换 ?0
通配符,您的查询将正确构建。
Employee
存储库也是如此,不同之处在于您必须在 @Query
的 [=] 中提供 Employee
的完全限定 class 名称24=]属性。
更多信息: