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

无法为kotlin和JpaRepository中的嵌套列表对象找到适当的构造函数错误

支阳波
2023-03-14

当JPA试图将查询的结果映射到结果存储库方法DTO时,我面临以下错误:

org.hibernate.hql.internal.ast.QuerySyntaxException: 
Unable to locate appropriate constructor on class [com.example.dto.User]. Expected arguments are: java.lang.String, java.lang.String, com.example.repository.DbRole

我在我的Kotlin项目中使用spring-boot-starter-data-jpaorg.jetbrains.Kotlin.plugin.jpa插件。我有一个如下定义的存储库:

@Repository
internal interface JdbcUserRepository : UserRepository, JpaRepository<DbUser, String> {

    override fun findUserByUsername(username: String): User?
}

请注意,JpaRepository(DbUser)使用的类型与findUserByUsername方法(User)重调的类型不同,而且在上面的错误中,JPA正确地找到了用户类(...class[com.example.dto.User]...)但角色不是。它期望目标DTO中有一个DbRole,出了什么问题。

@Entity
@Table(name = "user")
internal data class DbUser(
    @Id @Column val username: String,
    @Column val password: String,
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(
        name = "user_role",
        joinColumns = [JoinColumn(name = "username", referencedColumnName = "username")],
        inverseJoinColumns = [JoinColumn(name = "role_id", referencedColumnName = "id")]
    ) val roles: List<DbRole>
)

@Entity
@Table(name = "role")
internal data class DbRole(
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long,
    @Column val roleName: String,
    @Column val description: String
)
data class User(
    val username: String,
    val password: String,
    val roles: List<Role>
)

data class Role(val roleName: String, val description: String)

有没有人知道如何解决这个问题和JPA正确地找到并映射DbRole的嵌套实体列表到角色的嵌套DTO列表?

共有1个答案

金飞翼
2023-03-14

问题是数据库查询只能返回普通结果。持久性提供程序可以将其转换为具有嵌套实体列表的实体。至于DTO,您必须自己解决这个问题。

因此,您可以使用userdto和构造函数获得简单的结果,如下所示

public User(String username, String password, String roleName, String roleDescription) {
     this.username = username;
     this.password = password;
     roles = new ArrayList<>();
     roles.add(new Role(roleName, roleDescription));  
}

那么您需要像这样的存储库方法

@Query("select new com.example.dto.User(u.username, u.password, r.roleName, r.description) from DbUser u join u.roles r where u.username=:username")
List<User> findUserByUsername(@Param("username") String username);
public Optional<User> findUserByUsername(username) {
    List<User> users = findUserByUsername(username);

    if(users.isEmpty()) {
        return Optional.empty();
    }

    User user = users.get(0);
    if(users.size() > 1) {
         users.subList(1, users.size()).forEach(u -> user.getRoles().addAll(u.getRoles()));
    }

    return Optional.of(user);
}
 类似资料:
  • 当我尝试只使用Id作为值并删除列表时,它工作了。

  • 问题内容: 我是Java的新手,正在尝试为Minecraft制作一个mod,但我不知道如何解决此错误: 这是我的代码: 这是怎么回事,我正在尝试使字符串“ Username”重定向到另一个类。 问题答案: Java编译器告诉您不能构造对象,因为您对构造函数的调用与任何已知的构造函数都不匹配。 具体来说,编译器发现了两个构造函数: 但您致电给: 都不匹配。

  • 我创建了一个并将其附加到一个实体“Doctor”,在同一个实体上我附加了一个,它获取查询结果的列并将它们映射到一个专门创建的POJO类的构造函数。该查询还连接到一个JPA方法,该方法驻留在同一实体的存储库中。 但是,我不断得到一个错误,即找不到合适的构造函数,好像或POJO构造函数不同步。(堆栈跟踪在底部) 我的实体,和: 我直接在数据库上尝试了查询,它给出了预期的结果,所以我只是编写了selec

  • 我正在尝试将本机SQL结果映射到我的POJO。下面是配置。我在用Spring。 这是我的课 这里我是怎么称呼它的 但说到线

  • 从javase api 8开始,是不推荐的。因此,动态生成是首选的导出对象方式,如下所示: null 我的问题是,当出现在JavaE8 api中时,为什么编译器会出错?