2011-06-21 17 views
15

私は以下のEJB構造を持っています。 AnimalInventoryについては不思議ではありませんが、これらのクラスは構造を簡略化して示しています(更新:わかりやすい例を作成するためにクラス名を改訂しました)。IdTagの別の実装はBarcodeIdです。 IdTagからAnimalまたはInventoryへの逆の関係はなく、RfidTag.codeが一意であるとします。私はRetrieving Polymorphic Hibernate Objects Using a Criteria QueryHibernate polymorphic queryを読むが、これらの議論は私の質問に答えていないようだ。逆の関係のない多型CriteriaQuery

public interface ItemWithIdTag 
{ 
    IdTag getIdTag(); 
    void setIdTag(IdTag idTag); 
} 

@Entity public class Animal implements ItemWithIdTag,Serializable 
{ 
    @Id @GeneratedValue(strategy=GenerationType.AUTO) private long id; 

    @OneToOne(cascade = CascadeType.ALL) 
    private IdTag idTag; 
} 

@Entity public class Inventory implements ItemWithIdTag,Serializable 
{ 
    @Id @GeneratedValue(strategy=GenerationType.AUTO) private long id; 

    @OneToOne(cascade = CascadeType.ALL) 
    private IdTag idTag; 
} 

@Entity @Table(name = "IdTag") @Inheritance(strategy= InheritanceType.JOINED) 
public class IdTag implements Serializable 
{ 
    @Id @GeneratedValue(strategy=GenerationType.AUTO) private long id; 
    private Date created; 
} 

@Entity @Table(name = "RfidTag") 
public class RfidTag extends IdTag implements Serializable 
{ 
    private String code; 
} 

今、私はUnfortuately私は、次のerrrorを得る与えRfidTag.code

Animal ejb = bean.fEntityWithRfidTag(Animal.class,"myRfIdCode");よう
public <T extends ItemWithIdTag> T fOwner(Class<T> type, String catName) 
{ 
    CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); 
    CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(type); 
    Root<T> from = criteriaQuery.from(type); 

    Path<Object> path = from.join("idTag").get("code"); 

    CriteriaQuery<T> select = criteriaQuery.select(from); 
    select.where(criteriaBuilder.equal(path, catName)); 

    TypedQuery<T> q = em.createQuery(select); 
    T result = (T)q.getSingleResult();} 
    return result; 
} 

ためAnimalまたはInventoryのいずれかを照会する:

javax.ejb.EJBException: java.lang.IllegalArgumentException: 
Unable to resolve attribute [code] against path [null] 

私はこれが関連していることを前提とし継承はIdTag - >RfidTagAnimalは約0123しか知りませんであり、RfidTag.codeではありません。このようなクエリは可能ですか?

+0

一般的な基準ビルダーを使用したことがないので、これが問題かどうかはわかりませんが、問題は継承ではなく、実行するパス.get( "code")メソッドはnullです。少なくともそれは例外の状態です。あなたはfrom.join( "idTag")がnullを返さないと確信していますか?テーブルの名前が大文字の "I"で定義されているので、from.join( "IdTag")に変更する必要はありません。 – peshkira

+0

私が知る限り、 'from.join(" idTag ")'はテーブルの名前ではなく、 'ItemWithIdTag'の属性の名前を参照します。 – Thor

+0

yepp - それは本当です...ごめんなさい。ただし、joinメソッドの戻り値をチェックしましたか。それはnullではありませんか?ネストされた例外が何であるかを見るためにスタックトレース全体を投稿できますか? – peshkira

答えて

9

EclipseLinkを使用している場合、解決策は簡単です。あなたはHibernateを使用している場合は

Path<Object> path = ((Path) from.join("idTag").as(RfIdTag.class)).get("code"); 

、とあなたの方法を置き換えます:RfIdTagにキャストするパスの基準を変更します。これは、(「フィルタ直積を」)「に参加」を作る

public static <T extends ItemWithIdTag> T fOwner(Class<T> type, String catName) { 
    CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); 
    CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(type); 
    Root<T> fromType = criteriaQuery.from(type); 
    Root<RfIdTag> fromRfId = criteriaQuery.from(RfIdTag.class); 

    Path<Object> pathCode = fromRfId.get("code"); 
    Path<Object> pathIdTagType = fromType.get("idTag"); 
    Path<Object> pathIdTagRfId = fromRfId.get("id"); 

    CriteriaQuery<T> select = criteriaQuery.select(fromType); 
    select.where(
      criteriaBuilder.equal(pathCode, catName), 
      criteriaBuilder.equal(pathIdTagType, pathIdTagRfId)); 

    TypedQuery<T> q = em.createQuery(select); 
    return q.getSingleResult(); 
} 

」の間「T」および「RfIdTag」。

+0

印象深い!私はこれを単純化した例で検証し、これが正解であることを確認することができます。これを現実の世界に加えることは私にとっては不可能です。答えてくれてありがとう! – Thor

関連する問題