Java Hibernate @OneToMany Критерии Прогнозы, возвращающие NULL
У меня есть отношения Один ко многим Владелец-> Собака.
Я должен запросить собаку по ID, а также привести владельца в 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
is returnigll null Я пробую это, не используя никаких Трансформаторов.
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 ВСЕГДА возвращает при заполнении сущности maximun 1, они не могут заполнить обе таблицы [выбранные столбцы] в объекты [выбранные объекты]?
2 ответа
Я следую за этим постом Сложные проекции Hibernate и в результате я пишу свой собственный Transformer, потому что псевдоним resultTransformer для bean в hibernate на одном уровне.
вот мой простой результат 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;
}
Надеюсь, это кому-нибудь поможет.
Я написал ResultTransformer, который может решить вашу проблему. Это имя AliasToBeanNestedResultTransformer, проверьте его на github.