![](/img/trans.png)
[英]Hibernate Mapping Problems: Multiple Embeddables + ElementCollections
[英]Comparing ElementCollections of enums with QueryDSL and Hibernate
我們有2個實體:一個會說多種語言的員工和一個由員工進行的審查。
@Entity
public class Employee {
@ElementCollection
@CollectionTable(name = "employeeLanguage"
@Column(name = "language")
@Enumerated(EnumType.String)
private Set<Language> languages;
}
@Entity
public class Review {
@ManyToOne(fetch = FetchType.LAZY)
private Employee reviewer;
}
語言是一個簡單的枚舉:
public enum Language {
DE,
EN,
;
}
現在,我們要查詢評論的特定子集,如果它們已經完全涵蓋了特定員工的語言。 (specificReviewsSubset中的所有Review.reviewer.languages的聯合包含所有specificEmployee.languages)
我們正在嘗試以下查詢:
private BooleanExpression hasAllEmployeeLanguagesCovered (List<Review> reviews, Employee employee) {
return new JPASubQuery().from(e)
.where(e.eq(employee))
.where(e.languages.any().in(
new JPASubQuery().from(r).join(r.reviewer, e)
.where(r.in(reviews)).distinct().list(e.languages.any()
)
.exists();
}
但是我們收到以下錯誤:
java.lang.IllegalArgumentException: Undeclared path 'e_languages_ed0e7'.
Add this path as a source to the query to be able to reference it.
我們如何在路徑中添加e_languages? Afaik僅在我們擁有QLanguage並在e.languages上加入語言時才有效。 我們可以通過在Language上添加@Embeddable來生成此函數,但隨后休眠會抱怨在Language上缺少無參數的構造函數。
到目前為止,我們發現的唯一解決方法是拋棄@ElementCollection,而是引入一個EmployeeLanguage實體,該實體僅持有對雇員的引用和單個枚舉值。 此代碼產生的數據庫模式與問題中的數據庫模式相同,區別在於現在可以查詢語言:
@Entity
public class Employee {
@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL)
@Column(nullable = false)
@Getter @Setter
private Set<EmployeeLanguage> languages;
}
@Entity
public class EmployeeLanguage implements Serializable {
@Id
@ManyToOne(fetch = FetchType.LAZY)
@Getter @Setter
private Employee employee;
@Id
@Column(nullable=false)
@Enumerated(EnumType.STRING)
@Getter @Setter
private Language language;
}
現在,此查詢在進行少量重組后即可工作:
private BooleanExpression hasAllEmployeeLanguagesCovered (List<Review> reviews, Employee employee) {
return new JPASubQuery().from(el)
.where(el.employee.eq(employee))
.where(el.language.notIn(
new JPASubQuery().from(r).join(r.reviewer, e).join(e.languages, el)
.where(r.in(reviews)).list(el.language)
)
.notExists();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.