gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 13:31:43 28 4
gpt4 key购买 nike

当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正确找到User类之上的错误时(... class [com.example.dto.User] ...),但角色没有。期望目标DTO中有DbRole,这是什么问题。

DbUser是@Entity注释的类,它引用另一个@Entity注释的类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
)

以下是JPA必须将结果映射到的类:
data class User(
val username: String,
val password: String,
val roles: List<Role>
)

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

是否有人知道如何解决此问题,并且JPA正确找到DbRole的嵌套实体列表并将其映射到Role的嵌套DTO列表?

最佳答案

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

因此,您可以使用带有构造函数的User dto获得简单的结果,如下所示

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

您可以对 Kotlin使用相同的方法

关于hibernate - 无法在Kotlin和JpaRepository中为嵌套列表对象找到适当的构造函数错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60948133/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com