Reputation: 1063
I was stuck with getting result with @OneToMany mapping. Here are the model classes.
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
}
So my question is I want to load PropertyOwners where status is INACTIVE. I tried to write Criteria in different ways but I couldn't get the exact result. It is always return me all the PropertyOwners regardless of their status even though I add Restriction to the status. Here is one of the Criteria which I tried.
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;
}
Please provide me a proper solution for this problem. Thank you.
Upvotes: 0
Views: 3889
Reputation: 1063
Finally I found a way to get exact result from the PropertyOwners's status. The tricky part is when retrieve the result hibernate load all the matching entity regardless of the Restrictions
in createAlias
because of JoinType.INNER_JOIN
. So I put JoinType.LEFT_OUTER_JOIN
to the createAlias
and remove Restrictions
in createAlias
. I set the Restrictions
as usual way. Now it's giving the exact result matching the status.
Here is the modified method.
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;
}
Thank you.
Upvotes: 1