加入 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 在查询中强制使用左外连接