hibernate在派生类中找不到字段(怀疑泛型)

时间:2017-02-09 16:58:00

标签: java hibernate generics dao

我有一个水果类,一个延伸水果的班级香蕉和一个延伸香蕉的班级YellowBanana。 YellowBanana有一个名为" delicious"的领域。如果我试图访问"美味"在基于泛型的查询中,我得到以下异常:

Unable to locate Attribute  with the the given name [tasty] on this ManagedType [Fruit]

代码的简化版本是:

    @MappedSuperclass
    public abstract class Fruit implements Serializable
    {
    }

    @Entity
    @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
    public class Banana extends Fruit
    {
    }

    @Entity
    public class YellowBanana extends Banana
    {
       private boolean tasty = false;
    }

    public abstract class GenericDao<T extends Fruit>
    {
       public List<T> getObjects(Filter filter /* some criteria passed here */)
       {
          EntityManager entityManager = getEntityManager();
          CriteriaBuilder builder = entityManager.getCriteriaBuilder();
          CriteriaQuery<T> query = builder.createQuery(getPersistentClass());
          Root<T> root = query.from(getPersistentClass());

          List<Predicate> predicates = getFilterQueryRestrictions(root, builder, filter);
         if (predicates != null && !predicates.isEmpty())
            query.where(predicates.toArray(new Predicate[] {}));

          return entityManager.createQuery(query).getResultList();
       }

       private Class<T> getPersistentClass()
       {
          return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
       }
    }

    public class BananaDao extends GenericDao<Banana>
    {
        @Override
       protected List<Predicate> getFilterQueryRestrictions(Root<Banana> root, CriteriaBuilder builder,
         Filter filter)
       {
          List<Predicate> restrictions = new ArrayList<Predicate>();

          if (filter.forceTasty)
              // The exception is on the following line on root.get:
              restrictions.add(builder.equal(root.get("tasty"), 1));

          return restrictions;
       }
    }

正如您所看到的,我的目标是拥有一个通用DAO,它可以完成Fruit对象的所有CRUD操作。对于派生的entites,我正在创建实际的DAO类(在此示例中为BananaDao)。 getPersistentClass()返回实际的泛型类型。到目前为止,DAO的这种通用方式已经完成了所有操作,直到我传递了派生实例(本例中为YellowBanana)。

当然这只是一个简短的例子。现实中的水果是我所有人的基础(有很多)。我怎样才能让Hibernate找到&#34; delicious&#34;场?

2 个答案:

答案 0 :(得分:0)

tasty属性未在Banana上定义,就像您的DAO代码所期望的那样。您只在扩展类YellowBanana上定义了它,这是它在您的层次结构中适用的唯一实体类型。

如果要tastyBanana同时使用YellowBanana,您应该将其定义为Banana实体的一部分或作为映射超类的一部分类型和你的代码将正常工作。

答案 1 :(得分:-1)

您应该为该字段添加getter和setter,并使用注释

进行映射
@Column(name="tasty")
private boolean tasty = false;

public boolean isTasty(){
return tasty;
}

public void setTasty(boolean tasty){
this.tasty = tasty;
}