title: How to make HIbernate fetch all properties of root entity and only specific properties of associated entity?
body: <p>I have root entity <code>Hostel</code> and its single association <code>User owner</code>.</p>
  
  <p>When I fetch <code>Hostel</code> entity I need to eagerly fetch <code>User owner</code>, but only <code>owner</code>'s 3 properties : userId,firstName,lastName.</p>
  
  <p>For now my criteria query is :</p>
  
  <pre><code>Criteria criteria = currenSession().createCriteria(Hostel.class);
  
  criteria.add(Restrictions.ge("endDate", Calendar.getInstance()));
  if (StringUtils.notNullAndEmpty(country)) {
          criteria.add(Restrictions.eq("country", country));
  }
  
  Long count = (Long) criteria
              .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
              .setProjection(Projections.rowCount()).uniqueResult();
  
  criteria.setFetchMode("owner", FetchMode.SELECT);
  criteria.addOrder(Order.desc("rating"));
  
  // needed to reset previous rowCount projection
  criteria.setProjection(null);
  
  // retrieve owner association
  criteria.createAlias("owner", "owner", JoinType.LEFT_OUTER_JOIN)
          .setProjection(
                  Projections.projectionList()
                          .add(Projections.property("owner.userId"))
                          .add(Projections.property("owner.firstName"))
                          .add(Projections.property("owner.lastName")));
  
  criteria.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
  </code></pre>
  
  <p>Next, I do <code>criteria.list()</code> and I get sql statement which selects only <code>owner</code>'s 3 properties as specified in projection list. But it doesn't select any property of root <code>Hostel</code> entity.
  Generated query is:</p>
  
  <pre><code>select
      owner1_.user_id as y0_,
      owner1_.firstName as y1_,
      owner1_.lastName as y2_ 
  from
      HOSTEL this_ 
  left outer join
      USER owner1_ 
          on this_.owner_fk=owner1_.user_id 
  where
      this_.end_date&gt;=? 
      and this_.country=?        
  order by
      this_.rating desc limit ?
  </code></pre>
  
  <p>This query doesn't work because it returns five <code>Map</code>s which are empty. FIve maps are because there are five <code>Hostel</code> rows that match where condition. I created simple sql query and it works fine so the problem is only here.</p>
  
  <p>How to force hibernate to fetch all properties of root <code>Hostel</code> entity and only 3 properties of asociated <code>User owner</code> entity?</p>
  
  <p><strong>EDIT</strong>
  I tried to use <code>getSessionFactory().getClassMetadata(Hostel.class)</code> but it gave error about mapping enum in <code>Hostel</code>. So I fallback to list <code>Hostel</code> properties manually. For now my criteria query is:</p>
  
  <pre><code>// retrieve owner association
          criteria.createAlias("owner", "owner", JoinType.LEFT_OUTER_JOIN);
          criteria.setProjection(Projections.projectionList()
                  .add(Projections.property("hostelId"))
                  .add(Projections.property("address"))
                  .add(Projections.property("country"))
                  .add(Projections.property("region"))
                  .add(Projections.property("gender"))
                  .add(Projections.property("owner.userId"))
                  .add(Projections.property("owner.firstName"))
                  .add(Projections.property("owner.lastName")));
  
  List&lt;Hostel&gt; hostels = criteria.list();
  
  for (Hostel hostel : hostels) { // at this line I get error java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.home.hostme.entity.Hostel
              User owner = hostel.getOwner();
              System.out.println("owner=" + owner);
          }
  </code></pre>
  
  <p>Note that I removed <code>ALIAS_TO_ENTITY_MAP</code> result transformer. This generated such mysql query :</p>
  
  <pre><code>select
      this_.hostel_id as y0_,
      this_.address as y1_,
      this_.country as y2_,
      this_.region as y3_,
      this_.gender as y4_,
      owner1_.user_id as y5_,
      owner1_.firstName as y6_,
      owner1_.lastName as y7_ 
  from
      HOSTEL this_ 
  left outer join
      USER owner1_ 
          on this_.owner_fk=owner1_.user_id 
  where
      this_.end_date&gt;=? 
      and this_.country=? 
  order by
      this_.rating desc limit ?
  </code></pre>
  
  <p>At for-each loop  get such an error:</p>
  
  <pre><code>java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to com.home.hostme.entity.Hostel
      at com.home.hostme.dao.impl.HostelDaoImpl.findHostelBy(HostelDaoImpl.java:168)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
      at java.lang.reflect.Method.invoke(Unknown Source)
      at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
      at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
      at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
      at com.sun.proxy.$Proxy64.findHostelBy(Unknown Source)
      at com.home.hostme.service.HostelService.findHostelBy(HostelService.java:27)
      at com.home.hostme.service.HostelService$$FastClassByCGLIB$$74db5b21.invoke(&lt;generated&gt;)
      at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
      at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:698)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
      at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
      at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
      at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
      at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
      at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
      at com.home.hostme.service.HostelService$$EnhancerByCGLIB$$7af3bc10.findHostelBy(&lt;generated&gt;)
      at com.home.hostme.web.hostel.HostelController.doSearch(HostelController.java:94)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
      at java.lang.reflect.Method.invoke(Unknown Source)
      at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
      at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
      at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
      at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
      at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
      at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
      at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
      at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
      at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
      at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
      at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
      at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
      at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
      at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
      at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
      at java.lang.Thread.run(Unknown Source)
  </code></pre>
  
  <p>This error means that I don't have type <code>Hostel</code> in resulting list <code>hostels</code>.
  I even tried to find out class of elements in resulting list 'hostels' with this:</p>
  
  <pre><code>List hostels = criteria.list();
          System.out.println("firstRow.class=" + hostels.get(0).getClass());
  </code></pre>
  
  <p>It printed:</p>
  
  <pre><code>firstRow.class=class [Ljava.lang.Object;
  </code></pre>
  
  <p>Then I tried to set <code>ALIAS_TO_ENTITY_MAP</code> for new ProjectionList, but resulting list 'hostels' was:</p>
  
  <pre><code>[{}, {}, {}, {}, {}]
  </code></pre>
  
  <p>Five empty maps. Five because there are 5 rows in db(table hostel) matching where clause.</p>
  
  <p>Then I deleted projection list completely and hibernate retrieved 5 hostels and 5 associated <code>User owner</code>s and <code>owner</code>'s images as expected. </p>
  
  <p>THE PROBLEM is how to stop hibernate retrieve associated <code>Image</code> entity of associated <code>User owner</code>. The best would be to fetch only 3 specific props of associated <code>User owner</code>. </p>
  
  <p>Thank you!</p>