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=]属性。

更多信息: