У меня есть таблица, смоделированная в устаревшем файле .hbm.xml.
Устаревший код для извлечения строки использует org.hibernate.Criteria для получения uniqueResult (). При переходе на Hibernate 5.x Criteria устарела, поэтому я пытаюсь использовать CriteriaBuilder для достижения того же. Однако, когда я пытаюсь добавить ограничения (Hib 5.x) на основе того, что работало ранее (Hib 4.x), я получаю исключение IllegalArgumentException:
java.lang.IllegalArgumentException: Unable to locate Attribute with the the given name [xyzKey.plantName] on this ManagedType [com.foo.bar.Plant]
at org.hibernate.metamodel.model.domain.internal.AbstractManagedType.checkNotNull(AbstractManagedType.java:147)
at org.hibernate.metamodel.model.domain.internal.AbstractManagedType.getAttribute(AbstractManagedType.java:118)
at org.hibernate.metamodel.model.domain.internal.AbstractManagedType.getAttribute(AbstractManagedType.java:43)
at org.hibernate.query.criteria.internal.path.AbstractFromImpl.locateAttributeInternal(AbstractFromImpl.java:111)
at org.hibernate.query.criteria.internal.path.AbstractPathImpl.locateAttribute(AbstractPathImpl.java:204)
at org.hibernate.query.criteria.internal.path.AbstractPathImpl.get(AbstractPathImpl.java:177)
Plant.hbm.xml:
<hibernate-mapping>
<class lazy="false" name="com.foo.bar.Plant" table="Plant">
<meta inherit="false" attribute="extends">com.foo.bar.PlantBase</meta>
<id name="id" type="integer" column="plantID" unsaved-value="null">
<meta inherit="false" attribute="scope-set">protected</meta>
<generator class="native" />
</id>
<component name="xyzKey" class="com.foo.bar.PlantKey">
<meta inherit="false" attribute="use-in-tostring">true</meta>
<property name="plantName" type="string" index="xyzKeyndx" unique-key="plantKey">
<column name="plantName" />
</property>
<property name="xyzRevision" type="string" index="xyzKeyndx" unique-key="plantKey">
<column name="xyzRevision" length="100"/>
</property>
</component>
<property name="active" type="java.lang.Boolean" index="xyzKeyndx">
<column name="active" not-null="true"/>
</property>
<property name="description" type="string" not-null="false">
<meta inherit="false" attribute="field-description">User specified description. Does not need to be unique.</meta>
<meta inherit="false" attribute="use-in-tostring">false</meta>
<column name="descr" not-null="false" />
</property>
<property name="location" type="string" not-null="true">
<column name="location" />
</property>
</class>
</hibernate-mapping>
Работающий код на основе Hibernate 4.x:
protected Plant selectPlant(Session session, PlantKey xyzKey)
{
Criteria c = session.createCriteria(Plant.class);
if (Util.isEmpty(xyzKey.getXyzRevision()))
{
SimpleExpression plantName = Restrictions.eq("xyzKey.plantName", xyzKey.getPlantName());
SimpleExpression active = Restrictions.eq("active", true);
c.add(Restrictions.and(plantName, active));
}
else
{
c.add( Restrictions.eq("xyzKey", xyzKey) );
}
Plant plant = (Plant)c.uniqueResult();
return plant;
}
Неудачный код на основе Hibernate 5.x:
protected Plant selectPlant(Session session, PlantKey xyzKey)
{
ElapsedTimer timer = new ElapsedTimer();
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<Plant> criteriaQuery = criteriaBuilder.createQuery(Plant.class);
Root<Plant> root = criteriaQuery.from(Plant.class);
List<Predicate> restrictions = new ArrayList<>();
if ( FBCUtil.isEmpty(vpeKey.getVpeRevision()) )
{
restrictions.add(criteriaBuilder.equal(root.get("xyzKey.plantName"), xyzKey.getPlantName())); // FAILS HERE!
restrictions.add(criteriaBuilder.equal(root.get("active"), true));
}
else
{
restrictions.add(criteriaBuilder.equal(root.get("xyzKey"), xyzKey));
}
criteriaQuery.where(restrictions.toArray(new Predicate[restrictions.size()]));
Query<Plant> query = session.createQuery(criteriaQuery);
Plant plant = query.uniqueResult();
return plant;
}