![](/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.