当前位置: 首页 > 知识库问答 >
问题:

将新列从Spring本机查询映射到实体

陈项禹
2023-03-14
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 ....

当我直接对我的db运行本机查询时,结果集看起来就像我所期望的那样。

| id_value | MAPPED_ENTITY_ID_value | another value | word_value (YES) |

当我从我的JpaRepository运行本机查询时,除了word始终为null之外,所有的东西都在那里工作。我似乎想不出如何将额外的字符串单词结果映射到实体中的一个字段。

有没有办法把这个弄到地图上?还是必须为所有字段创建一个完整的@SQLResultSetMapping(),并与本机查询耦合?(希望不会)

我刚才是在概括。以下是我的疑问。

@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);

}

显然要复杂一些。

我可以通过使用命名查询将其映射到entity字段,但随后我松开了所有默认映射:

@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 ..

}

好吧,所以我越来越近了...似乎通过删除@columnresult我确实得到了默认映射,以及映射到上面的权限字段!看起来是这样的:

@SqlResultSetMapping(
        name="listPagedMapping"
)

最后一个问题是它不接受CountQuery,并且导致每当分页查询结果为多个页面时我的测试失败。看起来Spring Try想出自己的CountQuery,这是不正确的。

更新:3

共有1个答案

唐信瑞
2023-03-14

我一直没能按我想的那样工作。我确信我可以通过映射我的整个实体,但是,这将是一个艰苦的。最后,我通过使用NamedNativeQueries解决了这个问题,并通过Case语句映射了附加列。我的实体类现在注释如下:

@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
    )
})

我们也不再需要这个实体中的权限字段。我把它去掉了。

然后在我的存储库中:

Page<Object[]> listAccessibleInstances(
        @Param("username")final String username,
        @Param("instanceStates") final Set<String> instanceStates,
        final Pageable pageable);

就是这样!现在我的case语句的结果与每个实体一起返回。

 类似资料:
  • 问题内容: 我有一个带有本地查询的Spring Data Repository方法 并且我想将结果映射到Non-Entity POJO 。 是否可以,如果可以,请提供示例吗? 问题答案: 假设在Orid的答案中使用GroupDetails,您是否尝试过JPA 2.1 @ConstructorResult? 并在存储库界面中使用以下命令: 根据springJPA的数据文件,spring将首先尝试找到

  • 并且我希望将结果映射到非实体POJO。 是否可能?如果可能,请提供一个例子?

  • 我尝试使用的将本机SQL查询映射到POJO类,如下所示: 然后,为了在创建本机查询时使用声明的结果集映射,我通过它的名称引用它: 但这对我不起作用,我得到以下错误:

  • 我有一个复杂的本机查询,我正在尝试将其结果映射到非实体DTO类。我正在尝试使用的with 我的DTO类 我的entity类,它具有我将调用此本机查询结果的存储库接口。 存储库 当我从ItemRepository调用getItemDetails()时,出现以下错误: org.springframework.data.mapping.属性引用异常:没有属性项找到项目类型的详细信息 使用和并解决此问题的

  • 我使用Spring JDBC框架(如这里所示)从数据库中获取两列。我使用了“映射器”来实现“RowMapper”类,并执行如下查询: 这是我的映射器类: 而不是将查询结果存储到<code>中 如何在spring中将我的查询行存储到一个映射中,并将< code>ID设置为key,值为< code>account。

  • 我有一个场景,我想把从JPA存储库中的本机查询中提取的数据映射到自定义对象。 我的存储库代码如下: 我的自定义类代码如下: 但是我在运行应用程序时遇到了以下错误 原因:org。springframework。数据地图。PropertyReferenceException:找不到类型优惠券的属性FindTodayPoffer! 我应该移动名称查询和sql结果映射到我的实体类吗?问题是我不想污染我的实