It seems hibernate criteria is wrongly solved when the model has a specific shape:
<hibernate-mapping default-cascade="persist,merge,save-update" default-access="org.jspresso.framework.model.persistence.hibernate.property.EntityPropertyAccessor">
<class persister="org.jspresso.framework.model.persistence.hibernate.entity.persister.EntityProxyJoinedSubclassEntityPersister" dynamic-update="true" table="MOVEMENT" dynamic-insert="true" name="fr.model.Movement">
<id name="id" type="string">
<column name="ID" length="36"/>
<generator class="assigned"/>
</id>
<many-to-one insert="false" foreign-key="MOVEMENT_CURRENT_COMPOSITION_FK" update="false" not-null="true" name="currentComposition">
<column name="CURRENT_COMPOSITION_ID"/>
</many-to-one>
</class>
</hibernate-mapping>
<hibernate-mapping default-cascade="persist,merge,save-update" default-access="org.jspresso.framework.model.persistence.hibernate.property.EntityPropertyAccessor">
<class persister="org.jspresso.framework.model.persistence.hibernate.entity.persister.EntityProxyJoinedSubclassEntityPersister" dynamic-update="true" table="COMPOSITION" dynamic-insert="true" name="fr.gefco.geri.model.Composition">
<id name="id" type="string">
<column name="ID" length="36"/>
<generator class="assigned"/>
</id>
<list name="movements">
<key column="CURRENT_COMPOSITION_ID"/>
<list-index column="COMPOSITION_MOVEMENTS_SEQ"/>
<one-to-many class="fr.gefco.geri.model.Movement"/>
</list>
</class>
</hibernate-mapping>
<hibernate-mapping default-cascade="persist,merge,save-update" default-access="org.jspresso.framework.model.persistence.hibernate.property.EntityPropertyAccessor">
<class persister="org.jspresso.framework.model.persistence.hibernate.entity.persister.EntityProxyJoinedSubclassEntityPersister" dynamic-update="true" table="TRAIN" dynamic-insert="true" name="fr.gefco.geri.model.Train">
<id name="id" type="string">
<column name="ID" length="36"/>
<generator class="assigned"/>
</id>
<many-to-one unique="true" foreign-key="TRAIN_COMPOSITION_FK" name="composition">
<column name="COMPOSITION_ID"/>
</many-to-one>
</class>
</hibernate-mapping>
While using this mapping, the following criteria generates wrong SQL:
DetachedCriteria movementCriteria = DetachedCriteria.forClass(Movement.class);
movementCriteria.add(Restrictions.isNotNull(Movement.RTD));
movementCriteria.add(Restrictions.eq(Movement.PARKED, false));
DetachedCriteria compositionCriteria = movementCriteria.createCriteria(Movement.CURRENT_COMPOSITION);
compositionCriteria.add(Restrictions.eq(Composition.TRAIN, trainFilter));
DetachedCriteria wtoCriteria = movementCriteria.createCriteria(Movement.WAGON_TRANSPORT_ORDER);
wtoCriteria.add(Restrictions.eq(WagonTransportOrder.STATE, WagonTransportOrder.STATE_STARTED));
wtoCriteria.add(Restrictions.eq(WagonTransportOrder.LOAD_WEIGHT, 0.d));
While this version is ok:
EnhancedDetachedCriteria movementCriteria = EnhancedDetachedCriteria.forClass(Movement.class); //wtoCriteria.createCriteria(WagonTransportOrder.CURRENT_MOVEMENT);
movementCriteria.add(Restrictions.isNotNull(Movement.RTD));
movementCriteria.add(Restrictions.eq(Movement.PARKED, false));
DetachedCriteria compositionCriteria = movementCriteria.getSubCriteriaFor(movementCriteria, Movement.CURRENT_COMPOSITION);
DetachedCriteria trainCriteria = movementCriteria.getSubCriteriaFor(compositionCriteria, Composition.TRAIN);
trainCriteria.add(Restrictions.idEq(trainFilter.getId()));
DetachedCriteria wtoCriteria = movementCriteria.getSubCriteriaFor(movementCriteria, Movement.WAGON_TRANSPORT_ORDER);
wtoCriteria.add(Restrictions.eq(WagonTransportOrder.STATE, WagonTransportOrder.STATE_STARTED));
wtoCriteria.add(Restrictions.eq(WagonTransportOrder.LOAD_WEIGHT, 0.d));
Those 2 versions of the criteria should be processed the same way, and build the same SQL request.
This is not the case.
Case1:
select * from MOVEMENT this_
inner join WAGON_TRANSPORT_ORDER wagontrans2_
on this_.WAGON_TRANSPORT_ORDER_ID=wagontrans2_.ID
inner join COMPOSITION compositio1_
on this_.CURRENT_COMPOSITION_ID=compositio1_.ID
where this_.RTD is not null
and this_.PARKED=?
and compositio1_.ID=? <- WTF ?
and wagontrans2_.STATE=?
and wagontrans2_.LOAD_WEIGHT=?
With errors as the request is executed:
12:00:08,491 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] binding parameter [1] as [BIT] - false
12:00:08,491 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] binding parameter [2] as [VARCHAR] - STARTED
12:00:08,491 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] binding parameter [3] as [DOUBLE] - 0.0
12:00:08,492 WARN [org.hibernate.util.JDBCExceptionReporter] SQL Error: 0, SQLState: 07001
12:00:08,492 ERROR [org.hibernate.util.JDBCExceptionReporter] No value specified for parameter 4
Case2:
select from MOVEMENT this_
inner join WAGON_TRANSPORT_ORDER wagontrans3_
on this_.WAGON_TRANSPORT_ORDER_ID=wagontrans3_.ID
inner join COMPOSITION compositio1_
on this_.CURRENT_COMPOSITION_ID=compositio1_.ID
inner join TRAIN train2_
on compositio1_.ID=train2_.COMPOSITION_ID
where this_.RTD is not null
and this_.PARKED=?
and train2_.ID = ?
and wagontrans3_.STATE=?
and wagontrans3_.LOAD_WEIGHT=?
|