Spring存储库自动转换具有不同类类型的实体

时间:2015-04-30 10:42:09

标签: java spring mongodb spring-data

我正在使用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会自动转换为另一个。 如何避免这种自动铸造?或者如何指定我需要获得哪个类?

1 个答案:

答案 0 :(得分:3)

对于这两个存储库,您可以使用@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的完全限定类名,则查询不会抛出RuntimeException,但不会返回任何内容。在这种情况下,您可以在@Query

中使用通配符
@Query(value="{ '_class' : ?0 }")
List<Person> findAllManagers(String className);

然后,当您调用该方法时,您可以执行以下操作:

managerRepository.findAllManagers(Manager.class.getName());

提供的Manager.class.getName()将替换?0通配符,您的查询将正确构建。

Employee存储库也是如此,区别在于您必须在Employee的{​​{1}}属性中提供@Query的完全限定类名。< / p>

更多信息: