私は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に「おいしい」フィールドのマッピングを見つける方法を教えてください。
これでユーザーの問題は解決しません。 – Naros