代码之家  ›  专栏  ›  技术社区  ›  Andrea Bevilacqua

JPA投影:只选择一些项目和@OneToMany关系的整个实体

  •  0
  • Andrea Bevilacqua  · 技术社区  · 4 年前

    我有这两个实体:

    @Entity
    @Table(name = "ORGANIZATION")
    public class Organization implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        private String name;
    
        @OneToMany(mappedBy = "organization", fetch = FetchType.LAZY)
        private Set<OrganizationMeta> metas;
    
        public Organization() {
            super();
        }
    
        public Organization(Long id, String name, Set<OrganizationMeta> metas) {
            super();
            this.id = id;
            this.name = name;
            this.metas = metas;
        }
    
        // ... others fields ... getters and setters
    }
    
    @Entity
    @Table(name = "ORGANIZATION_META")
    public class OrganizationMeta implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @Enumerated(EnumType.STRING)
        @Column(name = "meta_key", length = 200, nullable = false)
        private OrganizationMetaKeyEnum metaKey;
    
        private String metaValue;
    
        @ManyToOne(optional = false, fetch = FetchType.LAZY)
        @JoinColumn(nullable = false)
        private Organization organization;
    
        // ... getters and setters ...
    }
    

    因此,一个组织可以有一个或多个OrganizationMeta,这是一个简单的情况。

    在ORGANIZAION_META表中有外键,因此它是关系的所有者。

    在组织实体中,我有一组由@OneToMany加载的元。

    我想使用投影编写一个查询,因为我只想要Organization实体的一些字段,但同时我想要整个OrganizationMeta实体。

    这是JPQL查询,但我总是遇到不同的错误

    @Query("select new net.feed.feedentity.domain.organization.Organization(organization.id, organization.name, organization.metas) from Organization organization left join fetch organization.metas where organization.id = ?1")
    

    在投影中选择@OneToMany字段的集合或列表似乎是不可能的。

    有可能做到吗?有人遇到过这个问题吗?

    0 回复  |  直到 4 年前
        1
  •  2
  •   Eric    4 年前

    我建议你通过以下方式接收数据 封闭投影技术 因为您需要的只是Organization类的一个子集。

    在这种情况下;您需要定义一个投影接口,该接口需要包含您感兴趣的属性的getter方法。这是你必须遵守的规则。名字应该匹配。

    界面看起来像这样:

    public interface OrganizationView {
        String getId();
        String getName();
        Set<OrganizationMeta> getMetas();
    }
    

    你可以给你的界面起任何名字,我用过 组织视图 .

    您将使用此接口作为返回类型。您可以在组织存储库中定义方法,如下所示。

    public interface OrganizationRepository extends JpaRepository<Organization, Long> {
    
        @Query("select organization.id, organization.name, organization.metas from Organization organization left join fetch organization.metas where organization.id = ?1")
        List<OrganizationView> findSubsetById(Long id);
    }
    

    最后,您将通过调用OrganizationView接口的方法来获取数据。

    编辑:你可以看看这个 page 关于用样本解释投影。