2017-02-09 6 views
0

私はFruitクラスを持っています。果物クラスはFruitクラスを拡張し、クラスYellowBananaクラスはBananaクラスを拡張しています。イエローバナナには「おいしい」というフィールドがあります。私は、ジェネリックに基づいてクエリで「おいしい」にアクセスしようとしている場合は、私は次の例外を取得しています:派生クラスのフィールドを見つけることができません(ジェネリック疑い)

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

することができますように私の目標はFruitオブジェクトのすべてのCRUD操作を行うジェネリックDAOを持つことです。派生したEntitesについては、実際のDAOクラス(この例ではBananaDao)を作成しています。 getPersistentClass()は実際のジェネリック型を返します。この一般的なDAOの方法は、派生したインスタンス(この例ではYellowBanana)を渡すまで、これまでのところすべての操作で美しく動作しています。

もちろん、これはほんの一例です。現実のフルーツは、すべての私のエンタイトの基本クラスです(たくさんあります)。 Hibernateに「おいしい」フィールドのマッピングを見つける方法を教えてください。

答えて

-1

あなたは、そのフィールドのゲッターとセッターを追加し、またあなたのDAOコードが期待するようtasty属性がBananaに定義されていない注釈に

@Column(name="tasty") 
private boolean tasty = false; 

public boolean isTasty(){ 
return tasty; 
} 

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

これでユーザーの問題は解決しません。 – Naros

0

を使用して、それをマップする必要があります。拡張クラス(YellowBanana)にのみ定義しました。このクラスは、階層内で適用可能なエンティティタイプです。

tastyBananaYellowBananaの両方に利用できるようにする場合は、あなたのBananaエンティティの一部として、またはマップされたスーパークラスの型の一部としてそれを定義する必要がありますし、あなたのコードはうまく動作します。

+0

しかし、Hibernateが生成している "バナナ"テーブルには "おいしい"フィールドが含まれているため、Hibernateはそのフィールドを正しく見つけています!そのDAOにyellowBananaインスタンスを渡すと、Hibernateは派生オブジェクトであることを知り、 "美味しい"フィールドの値を格納します。だから私はroot.get()に渡すときにそれが見つからない理由を理解できません。 – Wombat

+0

これで 'YellowBanana'に' tastey'が指定され、 'Banana'スーパータイプには指定されていないので、既存のエンティティ設定を反映するように質問のコードを変更する必要があります。 – Naros

+0

あなたの質問に表示されるようにコードをテストしただけで、そのコードは私が提示した理由で失敗します。コードが前のコメントを反映している場合、それは機能します。もう一度コードを見直さなければならないと思います。 – Naros

関連する問題