当 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
我在用着spring-boot-starter-data-jpa
and org.jetbrains.kotlin.plugin.jpa
我的 Kotlin 项目中的插件。我有一个像这样定义的存储库:
@Repository
internal interface JdbcUserRepository : UserRepository, JpaRepository<DbUser, String> {
override fun findUserByUsername(username: String): User?
}
请注意,JpaRepository (DbUser) 使用的类型与 findUserByUsername 方法 (User) 返回的类型不同,并且在上面的错误中,JPA 正确找到了 User 类(...类 [com.example.dto.User]...)但角色没有。它期望目标 DTO 中有一个 DbRole,这是错误的。
DbUser 是一个 @Entity 注解的类,并引用另一个名为 DbRole 的 @Entity 注解的类。两者定义如下:
@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列表?