hibernate - Crieria.Root 类无法获取作为复合键属性的本地属性
问题描述
我有实体类 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]
解决方案
看来您选择了不鼓励的映射。 https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/mapping.html#mapping-declaration-compositeid
不幸的是,这种方法意味着持久对象是它自己的标识符。除了对象本身之外,没有方便的“句柄”。您必须先实例化持久类本身的实例并填充其标识符属性,然后才能 load() 与复合键关联的持久状态。我们将此方法称为嵌入式复合标识符,并且不鼓励将其用于严肃的应用程序。
持久类必须重写 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 映射?注释现在很流行。
推荐阅读
- django - Django:CI/CD、BitBucket 管道和 VPS
- angular - 为什么@input 不加载变量中的数据?
- routes - 如何在 Rails 5 中使用自定义端口创建路由?
- c++ - Windows 是否有 S_IRGRP 和 S_IROTH 的替代方案?
- javascript - ReactJS API 身份验证:在现有状态转换期间无法更新
- python - 使用 Telethon for Telegram 时如何纠正“‘协程’对象没有属性‘数据’”错误?
- python - 检测并返回推文列表中每条推文的语言
- javascript - 如何在画布中对角裁剪图像
- reactjs - Typeerror: undefined is not an object (evalating view.getQuery) after login for componentDidMount in Emulator
- python - TypeError:描述符“fbind”需要一个“kivy._event.EventDispatcher”对象但收到一个“str”