3

我有一对多的关系所有者->狗。

我将通过 ID 查询狗,并以 EAGER 的方式带上所有者,我使用 Hibernate 4.1.6 设置了此代码,而不是使用 XML 映射。我只需要使用 Projections 来自 DOG 和 OWNER 的一些字段 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 = ?    

我的问题是... Dog 实例不是 null 并且所有字段都可以同时Dog.Owner返回 null 我尝试过不使用任何 Transformer。

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");

并且 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 个实体填充时返回它们不能将两个表 [选定列] 填充到对象 [选定对象] 中?

4

2 回答 2

5

我写了一个 ResultTransformer 可以解决你的问题。它的名字是 AliasToBeanNestedResultTransformer,在github上查看。

于 2013-09-11T01:14:17.750 回答
3

我关注这篇文章Complex Hibernate Projections,结果我编写了自己的Transformer,因为resultTransformer别名为休眠中的bean,深度为一级。

这是我的简单结果变压器

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;
}    

我希望它可以帮助某人。

于 2013-06-30T17:02:38.727 回答