我有三個物體:面試、問答。面試可以有很多問題(反之亦然,多對多),問題可以有很多答案(一對多)。
我以以下方式持久化和獲取物體:
@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 Answer
所有持久性操作都可以正常作業,采訪和問題都可以很好地創建,然后都可以正常獲取。但是當我創建答案(也很好)然后嘗試 findById 問題或采訪物體時,我收到以下錯誤(這個用于獲取問題):
"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"
它曾經對 findById (interview) 顯示相同的錯誤,但 FetchMode.JOIN 解決了??這個問題。由于某種原因, FetchMode.JOIN 被忽略以獲取答案(?)。除了使用 findById,我還嘗試使用 left join fetch 手動撰寫 HQL,但得到了相同的結果。我在這里想念什么?
面試單位:
顯示代碼片段
@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(),
)
問題物體:
顯示代碼片段
@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(),
)
回答物體:
顯示代碼片段
@Entity(name = "answer")
@RegisterForReflection
internal data class Answer (
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
val answerId: Long? = null,
@Column(name = "question_id", nullable = false)
val questionId: Long = Long.MIN_VALUE,
@ManyToOne(fetch = FetchType.LAZY)
@Fetch(FetchMode.JOIN)
@JoinColumn(
name="question_id",
foreignKey = ForeignKey(ConstraintMode.NO_CONSTRAINT),
nullable = false,
insertable = false,
updatable = false,
)
@JsonIgnore
val question: Question = Question(),
)
uj5u.com熱心網友回復:
在 Hibernate Reactive 中,惰性集合必須顯式獲取。如果您嘗試訪問惰性關聯而不先獲取它,您將看到該錯誤。
以下是獲取與 Panache 關聯的方法:
import org.hibernate.reactive.mutiny.Mutiny;
fun getInterview(interviewId: Long): Uni<Interview> {
return findById(interviewId)
.call(interview -> Mutiny.fetch(interview.questions))
}
請注意,以這種方式獲取關聯將導致對資料庫的額外查詢。根據用例的不同,在查詢中使用連接獲取來急切地加載關聯可能會更有效。這也應該有效:
fun getInterview(interviewId: Long): Uni<Interview> {
return find("from Interview i left join fetch i.questions where i.id = :id", Parameters.with("id", interviewId))
}
在這種情況下,Hibernate Reactive 將使用單個查詢加載所有內容。
此外,在使用 Hibernate 時,開發人員負責保持雙向關聯在雙方同步。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/531989.html
下一篇:如何強制變數公開kotlin
