如何在hibernate中向OneToMany映射添加限制

时间:2013-12-15 13:53:08

标签: java hibernate hibernate-criteria

我一直坚持使用@OneToMany映射获取结果。这是模型类。

Assessment.java

    @Entity
    @FilterDef(name = "tenantFilter", parameters = @ParamDef(name = "tenantIdParam", type = "string"))
    @Filters(@Filter(name = "tenantFilter", condition = "tenant_id = :tenantIdParam"))
    @Table(name = "assessment")
    public class Assessment extends Revenue implements Comparable<Assessment> {

    //other attriutes

    @ManyToOne(fetch = FetchType.LAZY)
        @Cascade(value = CascadeType.ALL)
        @JoinColumn(name = "property_id")
        private Property propertyAssessment;
    @Column(name = "tenant_id", nullable = false)
        private String tenantId;

//getters and setters
    }

Property.java

@Entity
@FilterDef(name = "tenantFilter", parameters = @ParamDef(name = "tenantIdParam", type = "string"))
@Filters(@Filter(name = "tenantFilter", condition = "tenant_id = :tenantIdParam"))
@Table(name = "property")
public class Property implements java.io.Serializable {

//other attributes

@ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "mas_gnd_id")
    private GramaNiladhariDivision gramaNiladhariDivision;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "mas_so_id", nullable = true)
    private SubOffice subOffice;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "mas_ward_id", nullable = true)
    private Ward ward;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "mas_road_id", nullable = true)
    private Road road;
    @Column(name = "side_of_property")
    private Character sideOfProperty;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "mas_pt_id", nullable = true)
    private PropertyType propertyType;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "property_description")
    private PropertyDescription propertyDescription;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "propertyAssessment")
    @Cascade(value = CascadeType.ALL)
    private List<Assessment> assessments = new ArrayList<Assessment>(0);
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "property")
    @Cascade(value = CascadeType.ALL)
    @LazyCollection(LazyCollectionOption.FALSE)
    private List<PropertyOwner> propertyOwners = new ArrayList<PropertyOwner>(0);

//getters and setters
}

PropertyOwner.java

@Entity
@FilterDef(name = "tenantFilter", parameters = @ParamDef(name = "tenantIdParam", type = "string"))
@Filters(@Filter(name = "tenantFilter", condition = "tenant_id = :tenantIdParam"))
@Table(name = "property_owner")
public class PropertyOwner implements java.io.Serializable {

//other attributes

@OneToOne(fetch = FetchType.EAGER)
    @Cascade(value = CascadeType.ALL)
    @JoinColumn(name = "person_id")
    private Person person;
    @Column(name = "is_main")
    private Boolean main;
    @ManyToOne(fetch = FetchType.LAZY)
    @Cascade(value = CascadeType.ALL)
    @JoinColumn(name = "property_id")
    private Property property = new Property();
    @Column(name = "tenant_id", nullable = false, updatable = false)
    private String tenantId;
    @Column(name = "status", columnDefinition = "varchar(255) default 'active'")
    private String status;

//getters and setters

}

所以我的问题是我想加载PropertyOwners,其状态为INACTIVE。我尝试以不同的方式编写Criteria,但我无法得到确切的结果。即使我在状态中添加限制,也始终将所有PropertyOwners返回给我,无论其状态如何。这是我尝试过的标准之一。

public Assessment getAssessmentById(Long assessmentId, Object tenantId) throws HibernateException {
        Session session = getSession(tenantId);
        Assessment result;
        result = (Assessment) session
                .createCriteria(Assessment.class)
                .setFetchMode("propertyAssessment", FetchMode.JOIN)
                .createAlias("propertyAssessment.propertyOwners", "propertyOwners", JoinType.INNER_JOIN,
                        Restrictions.ne("propertyOwners.status", ScandiumKeyBox.INACTIVE))
                .setFetchMode("propertyAssessment.subOffice", FetchMode.JOIN)
                .setFetchMode("propertyAssessment.ward", FetchMode.JOIN)
                .setFetchMode("propertyAssessment.gramaNiladhariDivision", FetchMode.JOIN)
                .setFetchMode("propertyAssessment.propertyDescription", FetchMode.JOIN)
                .setFetchMode("propertyAssessment.propertyType", FetchMode.JOIN)
                .setFetchMode("propertyAssessment.road", FetchMode.JOIN).setFetchMode("registerNumber", FetchMode.JOIN)
                .setFetchMode("registerPageNumbers", FetchMode.JOIN).setFetchMode("elgActivity", FetchMode.JOIN)
                .add(Restrictions.eq("id", assessmentId)).uniqueResult();
        return result;
    }

请为我提供适当的解决方案。谢谢。

1 个答案:

答案 0 :(得分:1)

最后,我找到了一种从PropertyOwners状态获得准确结果的方法。棘手的部分是在检索结果时hibernate加载所有匹配的实体,而不管Restrictions中的createAliasJoinType.INNER_JOIN而导致JoinType.LEFT_OUTER_JOIN。因此,我将createAlias添加到Restrictions并删除createAlias中的Restrictions。我像往常一样设置public Assessment getAssessmentById(Long assessmentId, Object tenantId) throws HibernateException { Session session = getSession(tenantId); Assessment result; result = (Assessment) session .createCriteria(Assessment.class) .setFetchMode("propertyAssessment", FetchMode.JOIN) .createAlias("propertyAssessment.propertyOwners", "propertyOwners", JoinType.LEFT_OUTER_JOIN) .setFetchMode("propertyAssessment.subOffice", FetchMode.JOIN) .setFetchMode("propertyAssessment.ward", FetchMode.JOIN) .setFetchMode("propertyAssessment.gramaNiladhariDivision", FetchMode.JOIN) .setFetchMode("propertyAssessment.propertyDescription", FetchMode.JOIN) .setFetchMode("propertyAssessment.propertyType", FetchMode.JOIN) .setFetchMode("propertyAssessment.road", FetchMode.JOIN).setFetchMode("registerNumber", FetchMode.JOIN) .setFetchMode("registerPageNumbers", FetchMode.JOIN).setFetchMode("elgActivity", FetchMode.JOIN) .add(Restrictions.eq("id", assessmentId)) .add(Restrictions.ne("propertyOwners.status", ScandiumKeyBox.INACTIVE)) .uniqueResult(); return result; } 。现在它给出了与状态匹配的确切结果。

这是修改后的方法。

{{1}}

谢谢。