【问题标题】:NativeQuery Spring Data return objectNativeQuery Spring Data 返回对象
【发布时间】:2017-11-10 04:51:12
【问题描述】:

我需要像这样在 Spring Data 中实现一个查询:-

Select User.name, sum(Activity.minutes) 
From User, Activity, ActivityStatus
Where User.id = ActivityStatus.userId
And Activity.id = ActivityStatus.activityId
AND ActivityStatus = "COMPLETED"
GROUP BY user.name;

所以我需要加入 3 个表,因此我必须使用 @QuerynativeQuery = true(如果我在这里错了,请纠正我)

所以我的 Repository 方法看起来像这样:-

@Query(value = "Select User.name, sum(Activity.minutes) as total_minutes
    From User, Activity, ActivityStatus
    Where User.id = ActivityStatus.userId
    And Activity.id = ActivityStatus.activityId
    AND ActivityStatus = "COMPLETED"
    AND User.Type = ?1
    GROUP BY user.name;",
    nativeQuery = true
    )
List<MyObj> getTotalActivityMinutesByUserType(String userType);

MyObj 类看起来像这样:-

public class MyObj {
    String name;
    long total_minutes;

// getter and setter methods

    public MyObj(String name, long total_minutes) {
        this.name = name;
        this.total_minutes = total_minutes;
    }
}

我的测试方法:-

@Test
public void TotalActivityTest() throws Exception {
    List<MyObj> objA = myRepository.getTotalActivityMinutesByUser("TEST");

}

我得到以下异常:-

org.springframework.core.convert.ConversionFailedException: 失败 从类型 [java.lang.Object[]] 转换为类型 [com.mycomp.MyObj] 为值'{TEST,5.0}';嵌套的 例外是 org.springframework.core.convert.ConverterNotFoundException:否 发现转换器能够从类型 [java.lang.String] 转换为 输入 [com.mycomp.dto.MyObj]

我需要一种将结果返回为MyObj 的方法。 (或者至少是一种将其转换为 MyObj 的方法)这可能吗?

编辑:

根据@Cepr0 的回答构建我的实体类如下所示:-

@Entity
public class ActivityStatus extends Base {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
    private Activity activity;

    @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
    private User user;

}

我不确定 JPQL 中的 JOIN 查询应该是什么样子...

【问题讨论】:

  • 您是否像 sqldeveloper 一样在 db ui 中执行了此查询,因为您在哪里使用连接来建立关系?
  • 是的,查询没有问题。从异常中您可以观察到结果是 {TEST,5.0} 这正是我在工作台上运行查询得到的结果。问题在于将结果集映射到 MyObj。
  • 查询返回对象数组,您将其存储在对象中。遍历对象数组并将其设置为对象

标签: java jpa spring-data nativequery


【解决方案1】:

只需使用ProjectionJPQL 查询:

public interface NameAndDuration {
    String getName();
    Long getDuaration();
}

@Query("select u.name as name, sum(a.minutes) as duration from User u join u.activityStatus st join st.activity a where st.status = "COMPLETED" and u.type = ?1 group by u.name")
List<NameAndDuration> getNameAndDurationByUserType(String userType);

List<NameAndDuration> list = getNameAndDurationByUserType("TEST");
String userName = list.get(0).getName();

此查询可能不完全符合您的需要,因为我不知道您的实体类的结构。但是,如果您向他们展示,我会更正查询...

【讨论】:

  • 感谢您的帮助,还没有完全工作。这是我的实体类的样子:-@Entity public class ActivityStatus extends Base { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH}) private Activity activity; @ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH}) private User user; } 在这种情况下,我应该如何在 JPQL 中编写 JOIN 查询?
  • 谢谢!我为凌乱的 cmets 感到抱歉,但我设法构建了正确的 JPQL 查询并且它有效!明天会尝试更多。你的答案肯定看起来更干净。所以我将其标记为答案。
  • 我发现成功的关键是使用接口(而不是类)并命名结果集名称以匹配接口。谢谢。
  • 为我工作!唯一要记住的是,接口的列顺序(在本机查询中)必须相同。 :)
【解决方案2】:

查询返回对象数组,您存储在普通对象中。遍历对象数组并将其设置为对象,如下所示

List<MyObj > test= new ArrayList<>();
List<Object[]> rows= query.list();
for (Object[] row : rows) {
MyObj temp=new MyObj (arg1,arg2);
temp.set((Dataype) row[0])//You need to create getters and setters for your pojo
..
test.add(temp);
}

【讨论】:

  • 感谢 Pradeep 的帮助,我很确定您的答案也很有效,但我猜 Cepr0 的答案更简洁。不过感谢您的帮助。
  • 很高兴您能够解决此问题。欢迎您。
【解决方案3】:

我实际上遇到了与此异常类似的问题。我有 3 个表:Project、Asset 和 ProjectAsset。 ProjectAsset 是一个项目可以有许多资产的参考表。所以我创建了 3 个存储库,每个实体一个。问题是我将@Query 放在 ProjectAssetRepository 中,但由于存储库扩展了 CrudRepository,这不起作用。 ProjectAssetId 是一个由 projectid 和assetid 组成的嵌入式id。我不能只返回此存储库中的 Asset 对象,因此我将方法移至 AssetRepository 并且一切正常。如果您正在使用交叉引用表,请确保您提取了正确的对象,否则您将遇到此异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-27
    • 2018-05-20
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 2013-05-01
    相关资源
    最近更新 更多