Spring Data Projection and Error:“在结果元组中找不到别名!确保您的查询定义了别名!”

Posted

技术标签:

【中文标题】Spring Data Projection and Error:“在结果元组中找不到别名!确保您的查询定义了别名!”【英文标题】:Spring Data Projection and Error: "No aliases found in result tuple! Make sure your query defines aliases!" 【发布时间】:2017-11-21 18:53:51 【问题描述】:

以下从 JPA 查询中获取 Spring 数据投影的方法对我不起作用:

https://***.com/a/45443776/1005607

我的桌子:

LOOKUP_T

id   description    display_order_num
------------------------------------
1    Category #1    1
2    Category #2    2

ACTIVITIES_T(activity_category_id 映射到 LOOKUP_T.id)

id  activity_category_id  activity_title
---------------------------------------
1      2                  Sleeping
2      2                  Eating
3      2                  Travel

Spring Data DAO 接口从这个连接中获取某些字段:

@Repository
public interface ActivitiesDAO extends JpaRepository<ActivitiesT, Integer> 

    @Query("select a.activityTitle, l.description as category, " + 
           "l.displayOrderNum as categoryDisplayOrderNum " + 
           "from ActivitiesT a, LookupT l " + 
           "where a.lookupT.id = l.id order by l.displayOrderNum asc ")
    public List<MySpringDataProjection> findCustom();


Spring 数据投影模型接口:

public interface MySpringDataProjection 

    public String getActivityTitle();

    public String getCategory();

    public Integer getCategoryDisplayOrderNum();


一切都与接受的答案相同。但收到此错误:

org.springframework.dao.InvalidDataAccessApiUsageException: No aliases found in result tuple! Make sure your query defines aliases!; nested exception is java.lang.IllegalStateException: No aliases found in result tuple! Make sure your query defines aliases!
    org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:381)
    org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:489)
    org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
    org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)

我不想在查询中使用select new Obj(..),它很脏并且依赖于我们抽象到 JPA 的 Hibernate。

我想让这种投影方法发挥作用。

具有我引用的(非工作)答案的相关问题, Spring data JPA: getting No aliases found in result tuple! error when executing custom query

【问题讨论】:

你想用投影做什么?一种更简单的方法可能只是获取 ActivityT 对象并从中获取查找信息。 我需要来自连接的特定字段。如果我使用的是域对象 (ActivityT),我需要一个 Eager Fetch 来获取关联,对吗?但也许我不想总是急切地获取 LookupID,但我大部分时间都想要惰性获取。这将使我得到我想要的东西,而不会在走 Lazy/Eager 路线时感到头疼。 你可以做几件事。创建一个通过 join fetch 进行 Eager fetch 的方法和另一个仅执行普通连接的方法,或者您可以获取 ActivityT 对象,然后在另一个查询中使用该对象来查询 LookupT 表。我个人没有弄乱 Spring 预测,所以我不知道如何真正回答您的原始问题,但可以建议解决方法以帮助您解决问题。上述方法通常是我为获取信息所做的工作 是的,问题是所有这些可怕的技术,如 Spring Data、JPA 和 ORM,都是为了“简化”和“改进”开发过程,结果我们所做的 90%时间在他们身边。只是评论。 询问人们 JPQL 应该是什么要求您提供实体类,而您没有。而且,如果您发现自己正在“解决”软件问题,那么您很可能会将它用于不适合的用途。但是你可以随心所欲地咆哮:-P 【参考方案1】:

我遇到了同样的问题。在尝试了几次更改后,我发现我们只需要在 NativeQuery 中为每一列添加“as”(即使列名没有改变)。在这里为您更改您的 sql,如下所示:

    @Query("select a.activityTitle **as activityTitle**, l.description as category, " + 
       "l.displayOrderNum as categoryDisplayOrderNum " + 
       "from ActivitiesT a, LookupT l " + 
       "where a.lookupT.id = l.id order by l.displayOrderNum asc ")

【讨论】:

【参考方案2】:

我有同样的问题,我想我解决了。我所做的是在所有字段中使用别名,即使它们具有相同的名称。在activityTitle 中也使用别名。像这样:

@Repository
public interface ActivitiesDAO extends JpaRepository<ActivitiesT, Integer> 

    @Query("select a.activityTitle as activityTitle, l.description as category, " + 
           "l.displayOrderNum as categoryDisplayOrderNum " + 
           "from ActivitiesT a, LookupT l " + 
           "where a.lookupT.id = l.id order by l.displayOrderNum asc ")
    public List<MySpringDataProjection> findCustom();


【讨论】:

【参考方案3】:

我认为您必须在接口中定义确切的名称方法,但我不确定这种方法是否适用于您的情况。

这里重要的是这里定义的属性与聚合根中的属性完全匹配。这允许像这样添加查询方法

在您的示例中,您可以尝试Open Projection

【讨论】:

以上是关于Spring Data Projection and Error:“在结果元组中找不到别名!确保您的查询定义了别名!”的主要内容,如果未能解决你的问题,请参考以下文章

[Spring Data JPA问题]Executing an update/delete query; nested exception is javax.persistence.Transacti

Clickhouse —— PROJECTION 创建物化删除

Clickhouse —— PROJECTION 创建物化删除

Clickhouse —— PROJECTION 创建物化删除

Grails distinct projection 获取不同项目的结果计数

响应式