我有实体类UniversityBasicInformation.java和UniversityBasicInformation.hbm.xml文件。我想编写一个条件查询。我的代码中root.get("surveyYear"), surveyYear)
出现错误。
错误表明
Java.lang.illegalArgumentsException:无法找到具有给定名称调查年份的本地属性。
在调试时,我确定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));
}
我希望将调查年份参数值添加为谓词。但是上述代码由于无法找到具有给定名称[surveyYear]的本地属性而报错了
答案 0 :(得分:0)
似乎您选择了不鼓励的映射。 https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/mapping.html#mapping-declaration-compositeid
不幸的是,这种方法意味着持久对象是其自己的标识符。除了对象本身之外,没有其他方便的“句柄”。您必须实例化持久性类本身的实例并填充其标识符属性,然后才能加载()与组合键关联的持久性状态。我们将此方法称为嵌入式复合标识符,不建议在严肃的应用中使用。
持久类必须重写equals()和hashCode()来实现复合标识符相等。它还必须实现Serializable。
要按整个键进行搜索,您需要覆盖equals()
并将整个UniversityBasicInformation
传递给
predicates.add(builder.equal(root, anUniversityBasicInformation));
我还调试了org.hibernate.query.criteria.internal.path.AbstractFromImpl.locateManagedType()
,并且模型中没有id
及其部分。
显然,这不是我们想要的。
我建议您遵循上面链接的建议,并通过使用一个类作为复合ID来修改映射。
https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/components.html#components-compositeid
最重要的是,您是否坚持使用xml映射?如今,注释很普遍。