加入 table 上的 Hibernate 标准显示意外结果
Hibernate Criterion on joined table showing unexpected results
我的标准如下所示:
public List<role> searchByFormStatus(boolean status) {
Criteria criteria = this.getSession().createCriteria(this.getPersistentClass());
List<role> result = (List<role>) criteria
.setFetchMode("role", FetchMode.JOIN)
.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
.createAlias("formApprovals", "f")
.add(Restrictions. eq("f.latestApproval", true))
.list();
return result;
}
乍一看应该可以,但无论我在参数中发送真值还是假值,结果总是
[{
"roleIsActive": true,
"roleName": "role1",
"roleNotes": "note",
"formApprovals": [
{
"approvalNotes": "good",
"approvedDate": 1449900000000,
"fkapprovedBy": 1,
"idformApproval": 1,
"latestApproval": true
},
{
"approvalNotes": "bad",
"approvedDate": 1449900000000,
"fkapprovedBy": 1,
"idformApproval": 2,
"latestApproval": false
}
}]
如您所见,即使我为 latestApproval 属性
创建了限制,"formApprovals" 也会将所有寄存器带到数据库中
父对象(角色)中的属性声明为:
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
public Set<FormApproval> getFormApprovals() {
return this.formApprovals;
}
public void setFormApprovals(Set<FormApproval> formApprovals) {
this.formApprovals = formApprovals;
}
检查控制台,我可以看到 hibernate 正确生成了 where 子句,但是,我可以看到之后还有其他查询,这些查询是否可能(我不知道为什么它们那里)正在覆盖我的标准?
有什么想法吗?
编辑
FormApproval Class
@Entity
@Table(name="FormApproval"
,catalog="catalog"
)
public class FormApproval implements java.io.Serializable {
private static final long serialVersionUID = 8L;
private int idformApproval;
private role role;
private Integer fkapprovedBy;
private Date approvedDate;
private String approvalNotes;
private boolean latestApproval;
public FormApproval() {
}
public FormApproval(int idformApproval, role role) {
this.idformApproval = idformApproval;
this.role = role;
}
public FormApproval(int idformApproval, role role, Integer fkapprovedBy, Date approvedDate, String approvalNotes, boolean latestApproval) {
this.idformApproval = idformApproval;
this.role = role;
this.fkapprovedBy = fkapprovedBy;
this.approvedDate = approvedDate;
this.approvalNotes = approvalNotes;
this.latestApproval = latestApproval;
}
@Id @GeneratedValue(strategy = IDENTITY)
@Column(name="IDFormApproval", unique=true, nullable=false)
public int getIdformApproval() {
return this.idformApproval;
}
public void setIdformApproval(int idformApproval) {
this.idformApproval = idformApproval;
}
@JsonIgnore
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="FKRole", nullable=false)
public role getrole() {
return this.role;
}
public void setrole(role role) {
this.role = role;
}
@Column(name="LatestApproval")
public boolean getLatestApproval() {
return this.latestApproval;
}
public void setLatestApproval(boolean latestApproval) {
this.latestApproval = latestApproval;
}
@Column(name="FKApprovedBy")
public Integer getFkapprovedBy() {
return this.fkapprovedBy;
}
public void setFkapprovedBy(Integer fkapprovedBy) {
this.fkapprovedBy = fkapprovedBy;
}
@Temporal(TemporalType.DATE)
@Column(name="ApprovedDate", length=10)
public Date getApprovedDate() {
return this.approvedDate;
}
public void setApprovedDate(Date approvedDate) {
this.approvedDate = approvedDate;
}
@Column(name="ApprovalNotes")
public String getApprovalNotes() {
return this.approvalNotes;
}
public void setApprovalNotes(String approvalNotes) {
this.approvalNotes = approvalNotes;
}
}
角色Class
@Entity
@Table(name="Role"
,catalog="catalog"
)
public class Role implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private int idRole;
private WorkType workType;
private String roleName;
private String roleNotes;
private boolean roleIsActive;
private Set<FormApproval> formApprovals = new HashSet<FormApproval>(0);
private Set<Topicrole> topicRoles = new HashSet<TopicRole>(0);
private Set<FormFeedBack> formFeedBacks = new HashSet<FormFeedBack>(0);
private Set<UserRole> userRoles = new HashSet<UserRrole>(0);
private Set<Interview> interviews = new HashSet<Interview>(0);
public Role() {
}
public Role(int idRole, WorkType workType, String roleName, boolean roleIsActive) {
this.idRole = idRole;
this.workType = workType;
this.RoleName = RoleName;
this.roleIsActive = roleIsActive;
}
public Role(int idRole, WorkType workType, String roleName, String roleNotes, boolean roleIsActive, Set<FormApproval> formApprovals, Set<TopicRole> topicRoles, Set<FormFeedBack> formFeedBacks, Set<UserRole> userRoles, Set<Interview> interviews) {
this.idRole = idRole;
this.workType = workType;
this.RoleName = RoleName;
this.roleNotes = roleNotes;
this.roleIsActive = roleIsActive;
this.formApprovals = formApprovals;
this.topicRoles = topicRoles;
this.formFeedBacks = formFeedBacks;
this.userRoles = userRoles;
this.interviews = interviews;
}
@Id @GeneratedValue(strategy = IDENTITY)
@Column(name="IDRole", unique=true, nullable=false)
public int getIdrole() {
return this.idRole;
}
public void setIdrole(int idRole) {
this.idRole = idRole;
}
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="FKWorkType", nullable=false)
public WorkType getWorkType() {
return this.workType;
}
public void setWorkType(WorkType workType) {
this.workType = workType;
}
@Column(name="RoleName", nullable=false)
public String getRoleName() {
return this.roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
@Column(name="RoleNotes")
public String getRoleNotes() {
return this.roleNotes;
}
public void setRoleNotes(String roleNotes) {
this.roleNotes = roleNotes;
}
@Column(name="RoleIsActive", nullable=false)
public boolean isRoleIsActive() {
return this.roleIsActive;
}
public void setRoleIsActive(boolean roleIsActive) {
this.roleIsActive = roleIsActive;
}
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
public Set<FormApproval> getFormApprovals() {
return this.formApprovals;
}
public void setFormApprovals(Set<FormApproval> formApprovals) {
this.formApprovals = formApprovals;
}
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
public Set<TopicRole> getTopicRoles() {
return this.topicRoles;
}
public void setTopicRoles(Set<TopicRole> topicRoles) {
this.topicRoles = topicRoles;
}
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
@JsonManagedReference
public Set<FormFeedBack> getFormFeedBacks() {
return this.formFeedBacks;
}
public void setFormFeedBacks(Set<FormFeedBack> formFeedBacks) {
this.formFeedBacks = formFeedBacks;
}
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
public Set<UserRole> getUserRoles() {
return this.userRoles;
}
public void setUserRoles(Set<UserRole> userRoles) {
this.userRoles = userRoles;
}
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="acnrole")
public Set<Interview> getInterviews() {
return this.interviews;
}
public void setInterviews(Set<Interview> interviews) {
this.interviews = interviews;
}
}
对于 EAGER 提取类型,嵌套条件应该适用于这种情况:
public List<role> searchByFormStatus(boolean status) {
Criteria criteria = this.getSession().createCriteria(this.getPersistentClass());
List<role> result = (List<role>) criteria
.createCriteria("formApprovals")
.add(Restrictions.eq("latestApproval", true))
.list();
return result;
}
您可以尝试将限制用作关联顶部 ON
子句的一部分。
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
@Where(clause=" latestApproval='true' ")
public Set<FormApproval> getFormApprovals() {
return this.formApprovals;
}
您还可以通过使用方法 org.hibernate.Criteria.createAlias(String associationPath, String alias, JoinType joinType)
指向关联路径来消除设置 FetchMode.JOIN
fetch
public List<role> searchByFormStatus(boolean status) {
Criteria criteria = this.getSession().createCriteria(Role.class, "role")
.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
.createAlias("role.formApprovals", "formApprovals", JoinType.LEFT_OUTER_JOIN);
return criteria.list();
}
更新:
对于旧版本的休眠,请使用下面的其他方法。其中 joinType
值对于 LEFT_OUTER_JOIN
为 1 并且 join 子句可以作为第四个参数传递。
public Criteria createAlias(String associationPath, String alias, int joinType, Criterion withClause) throws HibernateException;
使用
修复
.createCriteria("formApprovals","f",1,Restrictions.eq("f.latestApproval", status))
1 在查询中强制使用左外连接
我的标准如下所示:
public List<role> searchByFormStatus(boolean status) {
Criteria criteria = this.getSession().createCriteria(this.getPersistentClass());
List<role> result = (List<role>) criteria
.setFetchMode("role", FetchMode.JOIN)
.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
.createAlias("formApprovals", "f")
.add(Restrictions. eq("f.latestApproval", true))
.list();
return result;
}
乍一看应该可以,但无论我在参数中发送真值还是假值,结果总是
[{
"roleIsActive": true,
"roleName": "role1",
"roleNotes": "note",
"formApprovals": [
{
"approvalNotes": "good",
"approvedDate": 1449900000000,
"fkapprovedBy": 1,
"idformApproval": 1,
"latestApproval": true
},
{
"approvalNotes": "bad",
"approvedDate": 1449900000000,
"fkapprovedBy": 1,
"idformApproval": 2,
"latestApproval": false
}
}]
如您所见,即使我为 latestApproval 属性
创建了限制,"formApprovals" 也会将所有寄存器带到数据库中父对象(角色)中的属性声明为:
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
public Set<FormApproval> getFormApprovals() {
return this.formApprovals;
}
public void setFormApprovals(Set<FormApproval> formApprovals) {
this.formApprovals = formApprovals;
}
检查控制台,我可以看到 hibernate 正确生成了 where 子句,但是,我可以看到之后还有其他查询,这些查询是否可能(我不知道为什么它们那里)正在覆盖我的标准?
有什么想法吗?
编辑
FormApproval Class
@Entity
@Table(name="FormApproval"
,catalog="catalog"
)
public class FormApproval implements java.io.Serializable {
private static final long serialVersionUID = 8L;
private int idformApproval;
private role role;
private Integer fkapprovedBy;
private Date approvedDate;
private String approvalNotes;
private boolean latestApproval;
public FormApproval() {
}
public FormApproval(int idformApproval, role role) {
this.idformApproval = idformApproval;
this.role = role;
}
public FormApproval(int idformApproval, role role, Integer fkapprovedBy, Date approvedDate, String approvalNotes, boolean latestApproval) {
this.idformApproval = idformApproval;
this.role = role;
this.fkapprovedBy = fkapprovedBy;
this.approvedDate = approvedDate;
this.approvalNotes = approvalNotes;
this.latestApproval = latestApproval;
}
@Id @GeneratedValue(strategy = IDENTITY)
@Column(name="IDFormApproval", unique=true, nullable=false)
public int getIdformApproval() {
return this.idformApproval;
}
public void setIdformApproval(int idformApproval) {
this.idformApproval = idformApproval;
}
@JsonIgnore
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="FKRole", nullable=false)
public role getrole() {
return this.role;
}
public void setrole(role role) {
this.role = role;
}
@Column(name="LatestApproval")
public boolean getLatestApproval() {
return this.latestApproval;
}
public void setLatestApproval(boolean latestApproval) {
this.latestApproval = latestApproval;
}
@Column(name="FKApprovedBy")
public Integer getFkapprovedBy() {
return this.fkapprovedBy;
}
public void setFkapprovedBy(Integer fkapprovedBy) {
this.fkapprovedBy = fkapprovedBy;
}
@Temporal(TemporalType.DATE)
@Column(name="ApprovedDate", length=10)
public Date getApprovedDate() {
return this.approvedDate;
}
public void setApprovedDate(Date approvedDate) {
this.approvedDate = approvedDate;
}
@Column(name="ApprovalNotes")
public String getApprovalNotes() {
return this.approvalNotes;
}
public void setApprovalNotes(String approvalNotes) {
this.approvalNotes = approvalNotes;
}
}
角色Class
@Entity
@Table(name="Role"
,catalog="catalog"
)
public class Role implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private int idRole;
private WorkType workType;
private String roleName;
private String roleNotes;
private boolean roleIsActive;
private Set<FormApproval> formApprovals = new HashSet<FormApproval>(0);
private Set<Topicrole> topicRoles = new HashSet<TopicRole>(0);
private Set<FormFeedBack> formFeedBacks = new HashSet<FormFeedBack>(0);
private Set<UserRole> userRoles = new HashSet<UserRrole>(0);
private Set<Interview> interviews = new HashSet<Interview>(0);
public Role() {
}
public Role(int idRole, WorkType workType, String roleName, boolean roleIsActive) {
this.idRole = idRole;
this.workType = workType;
this.RoleName = RoleName;
this.roleIsActive = roleIsActive;
}
public Role(int idRole, WorkType workType, String roleName, String roleNotes, boolean roleIsActive, Set<FormApproval> formApprovals, Set<TopicRole> topicRoles, Set<FormFeedBack> formFeedBacks, Set<UserRole> userRoles, Set<Interview> interviews) {
this.idRole = idRole;
this.workType = workType;
this.RoleName = RoleName;
this.roleNotes = roleNotes;
this.roleIsActive = roleIsActive;
this.formApprovals = formApprovals;
this.topicRoles = topicRoles;
this.formFeedBacks = formFeedBacks;
this.userRoles = userRoles;
this.interviews = interviews;
}
@Id @GeneratedValue(strategy = IDENTITY)
@Column(name="IDRole", unique=true, nullable=false)
public int getIdrole() {
return this.idRole;
}
public void setIdrole(int idRole) {
this.idRole = idRole;
}
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="FKWorkType", nullable=false)
public WorkType getWorkType() {
return this.workType;
}
public void setWorkType(WorkType workType) {
this.workType = workType;
}
@Column(name="RoleName", nullable=false)
public String getRoleName() {
return this.roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
@Column(name="RoleNotes")
public String getRoleNotes() {
return this.roleNotes;
}
public void setRoleNotes(String roleNotes) {
this.roleNotes = roleNotes;
}
@Column(name="RoleIsActive", nullable=false)
public boolean isRoleIsActive() {
return this.roleIsActive;
}
public void setRoleIsActive(boolean roleIsActive) {
this.roleIsActive = roleIsActive;
}
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
public Set<FormApproval> getFormApprovals() {
return this.formApprovals;
}
public void setFormApprovals(Set<FormApproval> formApprovals) {
this.formApprovals = formApprovals;
}
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
public Set<TopicRole> getTopicRoles() {
return this.topicRoles;
}
public void setTopicRoles(Set<TopicRole> topicRoles) {
this.topicRoles = topicRoles;
}
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
@JsonManagedReference
public Set<FormFeedBack> getFormFeedBacks() {
return this.formFeedBacks;
}
public void setFormFeedBacks(Set<FormFeedBack> formFeedBacks) {
this.formFeedBacks = formFeedBacks;
}
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
public Set<UserRole> getUserRoles() {
return this.userRoles;
}
public void setUserRoles(Set<UserRole> userRoles) {
this.userRoles = userRoles;
}
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="acnrole")
public Set<Interview> getInterviews() {
return this.interviews;
}
public void setInterviews(Set<Interview> interviews) {
this.interviews = interviews;
}
}
对于 EAGER 提取类型,嵌套条件应该适用于这种情况:
public List<role> searchByFormStatus(boolean status) {
Criteria criteria = this.getSession().createCriteria(this.getPersistentClass());
List<role> result = (List<role>) criteria
.createCriteria("formApprovals")
.add(Restrictions.eq("latestApproval", true))
.list();
return result;
}
您可以尝试将限制用作关联顶部 ON
子句的一部分。
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="role")
@Where(clause=" latestApproval='true' ")
public Set<FormApproval> getFormApprovals() {
return this.formApprovals;
}
您还可以通过使用方法 org.hibernate.Criteria.createAlias(String associationPath, String alias, JoinType joinType)
FetchMode.JOIN
fetch
public List<role> searchByFormStatus(boolean status) {
Criteria criteria = this.getSession().createCriteria(Role.class, "role")
.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
.createAlias("role.formApprovals", "formApprovals", JoinType.LEFT_OUTER_JOIN);
return criteria.list();
}
更新:
对于旧版本的休眠,请使用下面的其他方法。其中 joinType
值对于 LEFT_OUTER_JOIN
为 1 并且 join 子句可以作为第四个参数传递。
public Criteria createAlias(String associationPath, String alias, int joinType, Criterion withClause) throws HibernateException;
使用
修复.createCriteria("formApprovals","f",1,Restrictions.eq("f.latestApproval", status))
1 在查询中强制使用左外连接