Проекции критериев Java Hibernate @OneToMany возвращают NULL

У меня есть отношения «Один ко многим» «Владелец-> Собака».

Я должен запросить собаку по идентификатору, а также привести владельца в EAGER. Я установил этот код, используя Hibernate 4.1.6, а не XML-отображение. мне нужны только некоторые поля от DOG и OWNER с использованием проекций. SQL, сгенерированный Hibernate, идеален, но мои объекты не заполняются, потому что DOG возвращает заполненные поля, но возвращается владелец DOG.OWNER==NULL вот код, который я использую до сих пор... Мой код entities.other для краткости опущен

@Entity
public class Owner implements Serializable
{
    Set<Dog>dogs=new HashSet<Dogs>(0);
    @OneToMany(fetch=FetchType.LAZY, mappedBy="owner")
    public Set<Dogs> getDogs(){return this.dogs}    
}   

@Entity
public class Dog implements Serializable
{
    private Owner owner;    
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="ownerid")
    public Owner getOwner(){return this.owner;}
 }  

вот мой метод.

public Dog getDogAndOwnerById(Integer dogId) 
{
    Projection p=Projections.projectionList()
    .add(Projections.property("d.id"),"id")
       .add(Projections.property("o.id"),"id");//and others fields
    Session session = getHibernateTemplate().getSessionFactory().openSession();        
    Criteria like = session.createCriteria(Dog.class,"d")
    .add(Restrictions.idEq(dogId)).setProjection(p)
    .setResultTransformer(Transformers.aliasToBean(Dog.class))
    .setFetchMode("owner",FetchMode.JOIN).createAlias("owner","o");        
    Dog dog = (Dog)like.uniqueResult();        
    //Object[]obj=(Object[])like.uniqueResult(); for(Object id:obj)System.out.println(id);
    //System.out.println(obj.length);
    session.close();
    return dog;
    //dog is OK BUT dog.OWNER is null.
}    

запрос идеален, вот SQL

select
    this_.ID as y0_,
    owner_.ID as y1_ 
from
    dog this_ 
inner join
    owner owner_ 
        on this_.ownerid=owner_.ID 
where
    and this_.ID = ?    

моя проблема в том, что... Экземпляр собаки НЕ является нулевым, и все поля в порядке, в то время как Dog.Owner возвращает нуль. Я попробовал это, не используя никаких трансформаторов.

Object[]obj=(Object[])like.uniqueResult(); for(Object id:obj)System.out.println(id);
System.out.println(obj.length);

И я вижу, что данные правильные, что Hibernate не возвращает мои объекты, верно? Что я делаю неправильно.

любая помощь очень ценится.

[обновить], если я использую это

Projection p=Projections.projectionList()
.add(Projections.property("d.id"),"id")
.add(Projections.property("o.status"),"status");

и статус принадлежит обеим таблицам, объект DOG заполняется, а другой нет.

если я использую

Projection p=Projections.projectionList()
.add(Projections.property("d.id"),"id")
.add(Projections.property("o.address"),"address");

и адрес принадлежит только владельцу.

Exception in thread "main" org.hibernate.PropertyNotFoundException: 
Could not find setter for address on class com.generic.model.Dog

Кажется, что Hibernate ВСЕГДА возвращается при максимальном заполнении 1 объекта, они не могут заполнить обе таблицы [выбранные столбцы] объектами [выбранными объектами]?


person chiperortiz    schedule 27.06.2013    source источник


Ответы (2)


Я написал ResultTransformer, который может решить вашу проблему. Он называется AliasToBeanNestedResultTransformer, проверьте его на github.

person Sami Andoni    schedule 11.09.2013
comment
Привет .. Я использую ваш трансформатор в течение длительного времени. Но отсутствует OneToMany вложенная выборка (о которой вы также указали в своем Github). Вы написали NestedTransformer для OneToMany? Спасибо.. - person The Coder; 16.08.2015
comment
любые такие реализации для OneToMany? - person C_B; 01.02.2017

я следую этому сообщению Complex Hibernate Projections, и в результате я пишу свой собственный Transformer, потому что псевдоним resultTransformer bean в спящем режиме на один уровень в глубину.

вот мой простой результат Transformer

public class MyOwnTransformer implements ResultTransformer
{
 @Override//the same order in projection list properties is the same returned by data array...  
 public Dog transformTuple(Object[]data,String[]alias)
 {return new Dog((Integer)data[0],new Owner((Integer)data[1]));} 
 @Override
 public List transformList(List dogs){return dogs;}//nothing to do here....
 }

и в моих критериях я исправляю такой код.

public Dog getDogAndOwnerById(Integer dogId) 
{
  Projection p=Projections.projectionList()
  .add(Projections.property("d.id"))//i dont need the alias anymore..
  .add(Projections.property("o.id"));
  Session session = getHibernateTemplate().getSessionFactory().openSession();        
  Criteria like = session.createCriteria(Dog.class,"d")
  .add(Restrictions.idEq(dogId)).setProjection(p)

  .setResultTransformer(new MyOwnTransformer())

  .setFetchMode("owner",FetchMode.JOIN).createAlias("owner","o");        
  Dog dog = (Dog)like.uniqueResult();        
  session.close();
  return dog;
}    

Я надеюсь, что это поможет кому-то.

person chiperortiz    schedule 30.06.2013
comment
Будет ли он поддерживать, если вложенный объект OneToMany (Collections) ? - person The Coder; 16.08.2015