E. *_* Dn 3 hibernate quarkus quarkus-panache hibernate-reactive
我有三个实体:采访、问答。面试可以有很多问题(反之亦然,多对多),问题可以有很多答案(一对多)。
我通过以下方式持久化和获取实体:
@ApplicationScoped
internal class InterviewRepository : PanacheRepository<Interview> {
fun persistInterview(interview: Interview): Uni<Interview> {
return Panache.withTransaction {
persist(interview)
}
}
fun getInterview(interviewId: Long): Uni<Interview> {
return findById(interviewId)
}
}
// same repos for Question and AnswerRun Code Online (Sandbox Code Playgroud)
所有持久性操作都工作正常,采访和问题都创建得很好,然后也都取得了很好的效果。但是当我创建答案(也很好)然后尝试 findById Question 或 Interview 实体时,我收到以下错误(此错误用于获取问题):
"org.hibernate.HibernateException: java.util.concurrent.CompletionException: org.hibernate.LazyInitializationException: HR000056: Collection cannot be initialized: com.my.company.question.Question.answers - Fetch the collection using 'Mutiny.fetch', 'Stage.fetch', or 'fetch join' in HQL"
Run Code Online (Sandbox Code Playgroud)
它曾经在 findById (面试)中显示相同的错误,但 FetchMode.JOIN 解决了这个问题。由于某种原因,FetchMode.JOIN 在获取答案时被忽略(?)。我没有使用 findById,还尝试使用 left join fetch 手动编写 HQL,但得到了相同的结果。我在这里缺少什么?
采访单位:
"org.hibernate.HibernateException: java.util.concurrent.CompletionException: org.hibernate.LazyInitializationException: HR000056: Collection cannot be initialized: com.my.company.question.Question.answers - Fetch the collection using 'Mutiny.fetch', 'Stage.fetch', or 'fetch join' in HQL"
Run Code Online (Sandbox Code Playgroud)
问题实体:
@Entity(name = "interview")
@RegisterForReflection
internal data class Interview (
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
val interviewId: Long? = null,
@Column(name = "client_id", nullable = false)
val clientId: Long = Long.MIN_VALUE,
@ManyToMany(mappedBy = "interviews", fetch = FetchType.LAZY)
@Fetch(FetchMode.JOIN)
val questions: MutableSet<Question> = mutableSetOf(),
)Run Code Online (Sandbox Code Playgroud)
回答实体:
@Entity(name = "question")
@RegisterForReflection
internal data class Question (
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
val questionId: Long? = null,
@Column(name = "client_id", nullable = true)
val clientId: Long? = null,
@OneToMany(mappedBy = "question", fetch = FetchType.LAZY)
@OnDelete(action = CASCADE)
@Fetch(FetchMode.JOIN)
val answers: MutableSet<Answer> = mutableSetOf(),
@ManyToMany(cascade = [CascadeType.ALL], fetch = FetchType.LAZY)
@JoinTable(
name = INTERVIEW_QUESTION_TABLE,
joinColumns = [JoinColumn(name = "question_id", referencedColumnName = "id")],
inverseJoinColumns = [JoinColumn(name = "interview_id", referencedColumnName = "id")]
)
@Fetch(FetchMode.JOIN)
@JsonIgnore
val interviews: MutableList<Interview> = mutableListOf(),
)Run Code Online (Sandbox Code Playgroud)
在 Hibernate Reactive 中,必须显式获取惰性集合。如果您尝试访问惰性关联而不先获取它,您将看到该错误。
以下是获取与 Panache 关联的方法:
import org.hibernate.reactive.mutiny.Mutiny;
fun getInterview(interviewId: Long): Uni<Interview> {
return findById(interviewId)
.call(interview -> Mutiny.fetch(interview.questions))
}
Run Code Online (Sandbox Code Playgroud)
请注意,以这种方式获取关联将导致对数据库进行额外的查询。根据用例,通过查询中的联接获取来急切地加载关联可能会更有效。这也应该有效:
fun getInterview(interviewId: Long): Uni<Interview> {
return find("from Interview i left join fetch i.questions where i.id = :id", Parameters.with("id", interviewId))
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,Hibernate Reactive 将通过单个查询加载所有内容。
此外,在使用 Hibernate 时,开发人员有责任保持双向关联在双方上同步。
| 归档时间: |
|
| 查看次数: |
1243 次 |
| 最近记录: |