Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
springjpa投影嵌套bean_Spring_Hibernate_Jpa_Spring Data Jpa - Fatal编程技术网

springjpa投影嵌套bean

springjpa投影嵌套bean,spring,hibernate,jpa,spring-data-jpa,Spring,Hibernate,Jpa,Spring Data Jpa,是否可以使用Spring JPA使用嵌套集合进行投影 我有以下两个简单的实体(用来解释问题) @实体 @表(name=“person”) 公共类Person实现可序列化{ 私有整数id; 私有字符串名称; @独身癖 private List addressList=new ArrayList(); } @实体 @表(name=“address”) 公共类地址实现可序列化{ 私有整数id; 私人城市; 私家弦街;; } 是否可以填写具有以下属性的人员投影?{person.name,address

是否可以使用Spring JPA使用嵌套集合进行投影

我有以下两个简单的实体(用来解释问题)

@实体
@表(name=“person”)
公共类Person实现可序列化{
私有整数id;
私有字符串名称;
@独身癖
private List addressList=new ArrayList();
}
@实体
@表(name=“address”)
公共类地址实现可序列化{
私有整数id;
私人城市;
私家弦街;;
}
是否可以填写具有以下属性的人员投影?{person.name,address.city}

我可能在单词投射的语义上错了。但问题是我需要实现什么。也许投射是不可能的,但有没有其他方法来实现最终目标?命名实体图

另外,请为Spring JPA而不是Spring JPA REST提出解决方案
提前感谢

我认为这不是通常使用数据JPA的情况。但您可以使用纯JPQL实现您的目标:

SELECT a.street, a.person.name FROM Address a WHERE …
此解决方案有两个缺点:

  • 它强制您拥有双向关系地址←→ 人
  • 它返回列表
  • 另一个解决方案(也是首选的JPA方式)是创建如下DTO:

    class MyPersonDTO {
      private String personName;
      private List<String> cities;
      public MyPersonDTO(String personName, List<Address> adresses) {
        this.personName = personName;
        cities = adresses
          .stream()
          .map(Address::getCity)
          .collect(Collectors.toList());
      }
    }
    
    SELECT NEW package.MyPersonDTO(p.name, p.addressList) FROM Person p WHERE …
    
    在这种情况下,返回类型将是
    List


    当然,您可以在
    @Query
    注释中使用任何此解决方案,它应该可以工作。

    您是对的,实体图正好用于此目的-控制字段加载

    从代码中动态创建实体图,或使用命名实体图注释目标实体,然后只使用它们的名称

    下面是如何修改
    Person
    类以使用命名实体图:

    @Entity
    @Table(name = "person")
    @NamedEntityGraph(name = "persion.name.with.city", 
                   attributeNodes = @NamedAttributeNode(value = "addressList", subgraph = "addresses.city"), 
                   subgraphs = @NamedSubgraph(name = "addresses.city", attributeNodes = @NamedAttributeNode("city")))
    public class Person implements Serializable {
    
        private Integer id;    
        private String name;
    
        @OneToMany
        private List<Address> addressList;
    }
    
    这同样适用于查询,而不仅仅是
    em.find
    方法


    查看更多详细信息。

    问题在于,您不能拥有多值字段的构造函数项。请参阅JPQL BNF
    “构造函数\项::=单值\路径\表达式\标量\表达式\聚合\表达式\标识\变量”
    @NeilStockton,但JPA提供程序可以提供自定义可能性。i、 hibernate允许这样做,所以你的代码变得完全不可移植;祝你好运,你只能靠自己了。@NeilStockton你多久从一个提供商迁移到另一个提供商?在我9年的JPA生涯中,我甚至一次也没有。@Arterm,有可能用实体图创建层次结构吗?例如AddressMini(仅加载城市的地址的实体图)Person->{name,List}加载的Cat->{name,List}加载的意思是,在另一个namedEntityGraph中引用namedEntityQuery进行嵌套Entities@user4772933这就是我在我的例子中所做的。我使用
    子图
    来定义地址(位于个人内部)应该包含哪些字段。永远不要为此创建额外的类(如
    AddressMini
    ),只需使用实体图告诉JPA要加载哪些字段即可。
    @Entity
    @Table(name = "person")
    @NamedEntityGraph(name = "persion.name.with.city", 
                   attributeNodes = @NamedAttributeNode(value = "addressList", subgraph = "addresses.city"), 
                   subgraphs = @NamedSubgraph(name = "addresses.city", attributeNodes = @NamedAttributeNode("city")))
    public class Person implements Serializable {
    
        private Integer id;    
        private String name;
    
        @OneToMany
        private List<Address> addressList;
    }
    
    EntityGraph graph = em.getEntityGraph("person.name.with.city");
    
    Map hints = new HashMap();
    hints.put("javax.persistence.fetchgraph", graph);
    
    return em.find(Person.class, personId, hints);