Hi!
I was a little confused when tow quite similar Criteria queries differed so much in performance.
Simplifying my model is as follow:
Element contain many PropertyValue (properties)
PropertyValue contain an AbstractProperty representing the type (property)
PropertyValue contain one Element representing the owner and one Element representing the value
PropertyValue contain the AbstractProperty definition
CRITERIA 1
Code:
session.createCriteria(Element.class).
                          add(Restrictions.gt("left", 2).
                          add(Restrictions.lt("right", 10)
           .createAlias("properties", "props").
                          .createAlias("props.property", "prop")
                          .add(Restrictions.eq("prop.url", "paper:author"))
           .createAlias("props.value", "vl")
                          .add(Restrictions.like("vl.name", (char) i + "%"))
                     .list();
CRITERIA 2
Code:
session.createCriteria(PropertyValue.class)
       .setProjection(Projections.property("owner"))
       .createAlias("property", "prop")
       .add(Restrictions.eq("prop.url", "paper:author"))
       .createAlias("value", "vl")
       .add( Restrictions.like("vl.name", (char) i + "%"))
       .createCriteria("owner")
           .add(Restrictions.gt("left", 2) 
           .add(Restrictions.lt("right", 10) .list();
The two criterias return the same results and generates the following SQLs:
CRITERIA 1
Code:
select
        this_.url as url0_3_,
        this_.name as name0_3_,
        this_.instance as instance0_3_,
        this_.description as descript4_0_3_,
        this_.insertedOn as insertedOn0_3_,
        this_.rate as rate0_3_,
        this_.parentID as parentID0_3_,
        this_.lft as lft0_3_,
        this_.rgt as rgt0_3_,
        propertyva1_.id as id2_0_,
        propertyva1_.elementID as elementID2_0_,
        propertyva1_.propertyID as propertyID2_0_,
        propertyva1_.valueID as valueID2_0_,
        propertyva1_.primitiveValue as primitiv5_2_0_,
        prop2_.url as url1_1_,
        prop2_.name as name1_1_,
        prop2_.inverseName as inverseN4_1_1_,
        prop2_.elementID as elementID1_1_,
        prop2_.domain as domain1_1_,
        prop2_.type as type1_1_,
        prop2_.minRange as minRange1_1_,
        prop2_.maxRange as maxRange1_1_,
        prop2_.propertyType as property2_1_1_,
        vl3_.url as url0_2_,
        vl3_.name as name0_2_,
        vl3_.instance as instance0_2_,
        vl3_.description as descript4_0_2_,
        vl3_.insertedOn as insertedOn0_2_,
        vl3_.rate as rate0_2_,
        vl3_.parentID as parentID0_2_,
        vl3_.lft as lft0_2_,
        vl3_.rgt as rgt0_2_ 
    from
        element this_ 
    inner join
        property_value propertyva1_ 
            on this_.url=propertyva1_.elementID 
    inner join
        abstract_property prop2_ 
            on propertyva1_.propertyID=prop2_.url 
    inner join
        element vl3_ 
            on propertyva1_.valueID=vl3_.url 
    where
        this_.lft>? 
        and this_.rgt<? 
        and prop2_.url=? 
        and vl3_.name like ?
CRITERIA 2
Code:
select
        this_.elementID as y0_ 
    from
        property_value this_ 
    inner join
        element element3_ 
            on this_.elementID=element3_.url 
    inner join
        abstract_property prop1_ 
            on this_.propertyID=prop1_.url 
    inner join
        element vl2_ 
            on this_.valueID=vl2_.url 
    where
        prop1_.url=? 
        and vl2_.name like ? 
        and element3_.lft>? 
        and element3_.rgt<?
The firts criteria is 4 times slower than the second, so I realized the first criteria returns lots of properties, so it must be trying to build lots of objects. The rest of the SQL is pretty much the same. 
How do I make the first query return only the Element and forget about all the other entities that are joined in the criteria? Is that really the problem????
Thanks!