org.hibernate.hql.ast.QuerySyntaxException: 无法找到合适的构造函数

3

我有两个映射到实体 UserGroup 的表。

@Entity
@Table(name = "T_COM_USER")
public class User {
    private String userName;
    @Column(name="F_USERNAME", length=60)
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
}

@Entity
@Table(name="T_COM_USERGROUP")
public class UserGroup{
    private String groupName;
    @Column(name="F_GROUPNAME", length=60)
    public String getGroupName() {
        return groupName;
    }
    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }
}

一个用户可以拥有多个组。我需要对它们进行建模,以便在前端以表格的形式显示所有用户及其所属组,如下所示:
+-------+----------------------+
| Users |        Groups        |
+-------+----------------------+
| User1 | Group1,Group2,Group3 |
| User2 | Group1,Group2        |
| User3 | Group2,Group4        |
+-------+----------------------+

因此,我创建了这个数据传输对象(DTO):

public class UserGroupsBean {
    private List<String> groupName;
    private String userName;
    public UserGroupsBean(String userName, List<String> groupName) {
        this.userName = userName;
        this.groupName = groupName;
    }
    // Getters
    public List<String> getGroupName() { return groupName; }
    public String getUserName() { return userName; }            
    // Setters
    public void setGroupName(List<String> groupName) { this.groupName = groupName; }
    public void setUserName(String userName) { this.userName = userName;}
}

我使用以下查询返回每个用户的所有组:
```sql SELECT * FROM user_groups; ```
String hql = "select new odatabase.service.beans.UserGroupsBean(userName,(select groupName from UserGroup) ) from User";

但是我得到了以下错误信息:

org.hibernate.hql.ast.QuerySyntaxException: 无法在类 [UserGroupsBean] 上定位适当的构造函数

尽管我有一个构造函数UserGroupsBean(String userName, List < String > groupName)

这是由什么原因引起的?我该如何解决它?


在HQL中,您需要在构造函数表达式中提供完全限定的类名,例如com.example.UserGroupsBean(...) - Tiny
是的,我在我的代码中写了完全限定的类名,错误在于它找不到具有这些属性(String 和 List<String>)的构造函数。 - Jad Chahine
在这样的查询中可能不支持List<T>(对于HQL我不确定,但在JPQL/JPA Criteria中是不允许的)。 - Tiny
1个回答

6
JPQL构造器表达式仅支持平面结果,因此您运气不佳。您可以使用像 SELECT u.userName, g.groupName FROM User u JOIN u.userGroups g 这样的查询,但是然后您必须自己减少结果集。
您想做的事情可以通过Blaze-Persistence Entity Views很好地完成。这里有一些示例代码。
@EntityView(User.class)
public interface UserGroupsBean {
    // The id of the user
    @IdMapping("id") int getId();

    String getUserName();

    @Mapping("userGroups.name")
    List<String> getGroupNames();
}

这基本上是一个带有一些元数据的数据传输对象(DTO)。以下是查询代码:

EntityManager entityManager = // jpa entity manager
CriteriaBuilderFactory cbf = // query builder from Blaze-Persistence
EntityViewManager evm = // manager that can apply entity views to query builders

CriteriaBuilder<User> builder = cbf.create(entityManager, User.class);
List<UserGroupsBean> result = evm.applySetting(
    builder, 
    EntityViewSetting.create(UserGroupsBean.class)
).getResultList();

这将生成类似于以下查询的查询。
SELECT u.id, u.userName, g.groupName FROM User u JOIN u.userGroups g

并且将自动为你映射DTO中的结果。

2
仅支持扁平结果的构造函数表达式,点赞! - Jad Chahine
有没有任何方法可以解决这个问题,而不需要添加blaze包? - Philip Kalela
有方法可以实现,但你可能不喜欢所需的实现方式:https://vladmihalcea.com/spring-jpa-dto-projection/ - Christian Beikov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接