我的Native查询中有一个case语句,我试图覆盖实体中的一个字段。
SELECT i.id, i.ONE_TO_ONE_ID, i.ANOTHER, CASE(WHEN condition THEN 'YES' WHEN another_condition THEN 'NO' ELSE 'MAYBE' END) as word ....
我使用JpaRepository作为本机查询,并使用分页。
当我直接对我的db运行本机查询时,结果集看起来就像我期望的那样。
| id_value | MAPPED_ENTITY_ID_value | another value | word_value (YES) |
当我从JpaRepository运行本机查询时,一切都在那里工作,除了word总是为null。我不能'似乎弄清楚如何将附加的String word结果映射到我的Entity中的字段。
有没有办法让它映射?或者我是否必须为我的所有字段和本机查询创建一个完整的@SqlResultSetMapping()? (希望不是)
更新:1
我在上面概括。这是我的查询。
@Query(
name = "listPagedMapping",
value = "SELECT DISTINCT i.ID, i.INSTANCE_ID, i.REGION, i.CNAME_STACK_ID, i.INSTANCE_STATE, i.IP_ADDRESS, i.EC2_ROLE_NAME, i.INSTANCE_OWNER, i.IS_MASTER, i.EC2_MASTER_ID, i.CNAME, i.EC2_START_TIMESTAMP, i.PRIVATE_DNS, i.INSTANCE_NAME, i.AUTO_TERMINATE, i.AUTO_TERMINATE_DATE, i.TERMINATION_ZONE, i.ADMIN_GROUP_AD_LDAP_ID, i.USER_GROUP_AD_LDAP_ID, (CASE WHEN i.INSTANCE_OWNER=:username THEN 'OWNER' WHEN i.ADMIN_GROUP_AD_LDAP_ID IN (g.AD_LDAP_ID) THEN 'ADMIN' WHEN i.USER_GROUP_AD_LDAP_ID IN (g.AD_LDAP_ID) THEN 'USER' END) as PERMISSION FROM USER u, USER_ACCESS_GROUPS g, EC2_PROVISIONING i WHERE i.INSTANCE_OWNER=:username and i.INSTANCE_STATE in (:instanceStates) or u.username=:username and i.INSTANCE_STATE in (:instanceStates) and g.USER_ID=u.USER_ID and (i.ADMIN_GROUP_AD_LDAP_ID IN (g.AD_LDAP_ID) or i.USER_GROUP_AD_LDAP_ID IN (g.AD_LDAP_ID))",
countQuery = "SELECT count(*) FROM (SELECT DISTINCT i.* FROM USER u, USER_ACCESS_GROUPS g, EC2_PROVISIONING i WHERE i.INSTANCE_OWNER=:username and i.INSTANCE_STATE in (:instanceStates) or u.username=:username and i.INSTANCE_STATE in (:instanceStates) and g.USER_ID=u.USER_ID and (i.ADMIN_GROUP_AD_LDAP_ID IN (g.AD_LDAP_ID) or i.USER_GROUP_AD_LDAP_ID IN (g.AD_LDAP_ID))) as ug",
nativeQuery = true)
Page<Ec2Instance> findAllByPermissionUserAdminOrOwnerAndInstanceStateIn(
@Param("username")final String username,
@Param("instanceStates") final Set<String> instanceStates,
final Pageable pageable);
}
显然有点复杂。
我可以使用命名查询将其映射到实体字段,但随后我将丢失所有默认映射:
@JsonInclude(JsonInclude.Include.NON_NULL)
@SuppressWarnings("unused")
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(exclude={"masterNode", "workers", "associatedBuckets"})
@Entity
@Table(name = "EC2_PROVISIONING")
@SqlResultSetMapping(
name="listPagedMapping",
columns = {
@ColumnResult(name = "permission", type = String.class)
}
)
@NamedNativeQuery(
name = "listAccessibleInstances",
query = ACCESSIBLE_QUERY,
resultSetMapping = "listPagedMapping"
)
public class Ec2Instance {
....
private String permission;
@column(name = "INSTANCE_ID")
private String instanceId;
@ManyToOne
@JoinColumn(name = "EC2_MASTER_ID")
private Ec2Instance masterNode;
@Setter(AccessLevel.NONE)
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "WORKER_EC2_NODES", joinColumns = { @JoinColumn(name = "EC2_MASTER_ID") }, inverseJoinColumns = {
@JoinColumn(name = "ID") })
private Set<Ec2Instance> workers = new HashSet<>();
... More fields ..
}
我想,我希望有一种方法可以在ORM完成的默认映射之上提供单个映射。上面的代码只导致Content PERMISSION的可分页,而不是整个实体+权限。
更新:2
好的,所以我越来越近了......似乎删除了@ColumnResult
我得到了默认的映射,加上映射的PERMISSION字段!看起来像这样:
@SqlResultSetMapping(
name="listPagedMapping"
)
最后一个问题是它不接受我的CountQuery,并且每当分页查询产生多个页面时,我的测试都会失败。看起来Spring尝试提出自己的CountQuery,这是不正确的。
更新:3
要完成此操作,看起来我可以按照此处所述提供计数查询:Spring Data - Why it's not possible to have paging with native query
我会先试试并更新回来。
答案 0 :(得分:0)
我从来没有按照我想要的方式工作。我相信我可以通过映射我的整个实体,但是,这本来是艰苦的。我最后通过使用NamedNativeQueries解决了这个问题,并在我的Case语句中使用了附加列的映射。我的实体类现在注释如下:
docker exec -i -t <container_name> bash
我们也不再需要此实体中的权限字段。我删除了。
然后在我的存储库中:
@JsonInclude(JsonInclude.Include.NON_NULL)
@SuppressWarnings("unused")
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(name = "EC2_PROVISIONING")
@SqlResultSetMappings({
@SqlResultSetMapping(
name = "listPagedMapping",
entities = {
@EntityResult(
entityClass = Ec2Instance.class
)
},
columns = {@ColumnResult(name = "permission", type = String.class)}
),
@SqlResultSetMapping(name = "listPagedMapping.count", columns = @ColumnResult(name = "cnt"))
})
@NamedNativeQueries({
@NamedNativeQuery(
name = "Ec2Instance.listAccessibleInstances",
query = ACCESSIBLE_QUERY,
resultClass = Ec2Instance.class,
resultSetMapping = "listPagedMapping"
),
@NamedNativeQuery(
name = "Ec2Instance.listAccessibleInstances.count",
resultSetMapping = "listPagedMapping.count",
query = ACCESSIBLE_QUERY_COUNT
)
})
多数民众赞成!现在,我的case语句的结果随每个实体一起返回。
Object [0] =原始,默认映射实体。 对象[1] =权限