Hi All,
One Assessment can have many Property and one Property can have many PropertyOwner.
Yesterday I faced a problem with load some data based on the Criterion which I wrote to @OneToMany mapping. I Google all over the day but I couldn't come up with a proper solution. Finally I found an answer by my self. I thought of sharing with you in my blog.
Here is the problem explanation. Result which I want to get mapped with couple of Hibernate model classes but here I take 3 classes which is basically involve in add Criterion to the @OneToMany mapping.
One Assessment can have many Property and one Property can have many PropertyOwner.
Code snippet of model classes as below. (These are not the complete 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 implements Serializable { @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @ManyToOne(fetch = FetchType.LAZY) @Cascade(value = org.hibernate.annotations.CascadeType.ALL) @JoinColumn(name = "property_id") private Property propertyAssessment; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "elg_activity_id", nullable = false) private ElgActivity elgActivity; @Column(name = "tenant_id", nullable = false) private String tenantId; // other attributes // 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 Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id", unique = true, nullable = false) private Long id; @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); @Column(name = "tenant_id", nullable = false) private String tenantId; // other attributes // getters and setters }
PropertyOwner.java
My query is to get the PropertyOwner by their status. PropertyOwner status can be either ACTIVE or INACTIVE. My requirement is to get all the ACTIVE PropertyOwner. Here is the method I wrote to get the result.
Thank you.
@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 Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id", unique = true, nullable = false) private Long id; @OneToOne(fetch = FetchType.EAGER) @Cascade(value = CascadeType.ALL) @JoinColumn(name = "person_id") private Person person; @ManyToOne(fetch = FetchType.LAZY) @Cascade(value = CascadeType.ALL) @JoinColumn(name = "property_id") private Property property = new Property(); @Column(name = "status") private String status; @Column(name = "tenant_id", nullable = false) private String tenantId; // other attributes // getters and setters }
@Override public Assessment getAssessmentById(Long assessmentId, Object tenantId) throws HibernateException { Session session = getSession(tenantId); Assessment result = (Assessment) session.createCriteria(Assessment.class) .createAlias("propertyAssessment", "propertyAssessment") .createAlias("propertyAssessment.propertyOwners", "propertyOwner", JoinType.LEFT_OUTER_JOIN) .add(Restrictions.eq("id", assessmentId)) .add(Restrictions.ne("propertyOwner.status", ScandiumKeyBox.INACTIVE)) .uniqueResult(); return result; }
The tricky point here is the JoinType.LEFT_OUTER_JOIN. By default if you wrote a createAlias and lazy load object then default JoinType would be JoinType.INNER_JOIN. This will load all matching objects regardless of your Criterion to that object. Here I overcome that problem with LEFT_OUTER_JOIN. Other thing is here I load the exact result by matching the id (primary key).
If you want to load list of objects, make sure to set below line to the criteria.
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
Hope this would be helpful you to get the exact result in @OneToMany mapping by adding Criterion.
Thank you.
No comments:
Post a Comment