Spring存储库自动转换具有不同类类型的实体 [英] Spring repository auto casts entities with different class types

查看:47
本文介绍了Spring存储库自动转换具有不同类类型的实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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存储库也是如此,区别在于您必须在@Queryvalue属性中提供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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆