我有一对多关系所有者 - >狗。
我将通过ID查询狗以及以EAGER方式引入所有者我使用Hibernate 4.1.6设置此代码而不使用XML映射。我只需要DOG和OWNER使用Projections的一些字段
Hibernate生成的SQL是完美的,但我的对象没有填充,因为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 = ?
我的问题是...狗实例不为空且所有字段都是O.K同时Dog.Owner
是returnig 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总是返回最大1实体填充它们不能将两个表[selected columns]填充到对象[selected objects]中?
答案 0 :(得分:5)
我写了一个可以解决问题的ResultTransformer。它的名字是AliasToBeanNestedResultTransformer,请在github上查看。
答案 1 :(得分:3)
我关注这篇文章Complex Hibernate Projections,结果我编写了自己的Transformer,因为resultTransformer在一个级别深度的hibernate中为bean做了别名。
这是我简单的resultTransformer
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;
}
我希望它对某人有所帮助。