0

I have Entity class UniversityBasicInformation.java and UniversityBasicInformation.hbm.xml files. I want to write a criteria query. I am getting error at root.get("surveyYear"), surveyYear) in my code.

The error says that

Java.lang.illegalArgumentsException: unable to find local attribute with the given name survey year.

On Debug I identified that Composite key attributes are unable to be identified by JPA.

public class UniversityBasicInformation implements Serializable{        
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    @JsonProperty
    private String aisheCode;
    @JsonProperty
    private Integer surveyYear;
    @JsonProperty
    private String state;
    @JsonProperty
    private String name;
    @JsonProperty
    private String district;
    @JsonProperty
    private String type;
}
<hibernate-mapping>
    <class name="gov.nic.aishe.read.pojo.UniversityBasicInformation" table="university_basic_information"
        schema="readonly">
        <composite-id>
            <key-property name="aisheCode" type="java.lang.String">
                <column name="aishe_code" />
            </key-property>
            <key-property name="surveyYear" type="java.lang.Integer">
                <column name="survey_year" />
            </key-property>
        </composite-id>
        <property name="state" type="java.lang.String">
            <column name="state" />
        </property>
        <property name="district" type="java.lang.String">
            <column name="district" />
        </property>
        <property name="type" type="java.lang.String">
            <column name="type" />
        </property>        
    </class>

</hibernate-mapping>
public List<UniversityBasicInformation> getUniversityList(Integer surveyYear, String stateCode, String type,
        String speciality, String districtCode) {

    CriteriaBuilder builder = sessionFactory.getCurrentSession().getCriteriaBuilder();
    CriteriaQuery<UniversityBasicInformation> criteriaQuery = builder.createQuery(UniversityBasicInformation.class);
    Root<UniversityBasicInformation> root = criteriaQuery.from(UniversityBasicInformation.class);


    List<Predicate> predicates = new ArrayList<Predicate>();

    predicates.add(builder.equal(root.get("surveyYear"), surveyYear)); //line with error

    if (stateCode != null) {

        predicates.add(builder.equal(root.get("state"), stateCode));

    }

I expect that survey year parameter value to be added as predicate. But the above code is giving error as unable to find local attribute with given name [surveyYear]

barbsan
  • 3,418
  • 11
  • 21
  • 28

1 Answers1

0

It seems you have chosen a discouraged mapping. https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/mapping.html#mapping-declaration-compositeid

Unfortunately, this approach means that a persistent object is its own identifier. There is no convenient "handle" other than the object itself. You must instantiate an instance of the persistent class itself and populate its identifier properties before you can load() the persistent state associated with a composite key. We call this approach an embedded composite identifier, and discourage it for serious applications.

The persistent class must override equals() and hashCode() to implement composite identifier equality. It must also implement Serializable.

To search by entire key, you would need to override equals() and pass entire UniversityBasicInformation to

predicates.add(builder.equal(root, anUniversityBasicInformation));

I also debugged org.hibernate.query.criteria.internal.path.AbstractFromImpl.locateManagedType() and neither id nor its parts are there in the model. Clearly, this is not what we want.

I suggest you follow the advice from the link above and modify your mapping by using a class for your composite id.

https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/components.html#components-compositeid

On top of that, are you stuck with xml mapping? Annotations are prevalent these days.

Community
  • 1
  • 1
Lesiak
  • 22,088
  • 2
  • 41
  • 65