JPA 投影:select 只有一些项目和@OneToMany 关系的整个实体
JPA Projection: select only some items and an entire entity of @OneToMany relationship
我有这两个实体:
@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 ...
}
所以一个Organization可以有一个或多个OrganizationMeta,这是一个简单的情况。
在ORGANIZATION_METAtable中有外键,所以它是关系的所有者。
在组织实体中,我有一组由@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")
在投影中似乎不可能select,@OneToMany 字段的集合或列表。
这可以吗?有人遇到过这个问题吗?
我建议您通过对组织实体执行 封闭投影技术 来接收数据,因为您需要的只是组织 class 的一个子集。
那样的话;您需要定义一个投影接口,该接口需要包含您感兴趣的属性的 getter 方法。这是你必须遵守的规则。名字应该匹配。
界面将如下所示:
public interface OrganizationView {
String getId();
String getName();
Set<OrganizationMeta> getMetas();
}
你可以给你的界面取任何名字,我用的是OrganizationView。
您将使用此接口作为 return 类型。您可以在组织存储库中定义方法,如下所示。
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关于样本投影的解释。
我有这两个实体:
@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 ...
}
所以一个Organization可以有一个或多个OrganizationMeta,这是一个简单的情况。
在ORGANIZATION_METAtable中有外键,所以它是关系的所有者。
在组织实体中,我有一组由@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")
在投影中似乎不可能select,@OneToMany 字段的集合或列表。
这可以吗?有人遇到过这个问题吗?
我建议您通过对组织实体执行 封闭投影技术 来接收数据,因为您需要的只是组织 class 的一个子集。
那样的话;您需要定义一个投影接口,该接口需要包含您感兴趣的属性的 getter 方法。这是你必须遵守的规则。名字应该匹配。
界面将如下所示:
public interface OrganizationView {
String getId();
String getName();
Set<OrganizationMeta> getMetas();
}
你可以给你的界面取任何名字,我用的是OrganizationView。
您将使用此接口作为 return 类型。您可以在组织存储库中定义方法,如下所示。
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关于样本投影的解释。