条件を使用して次のクエリを作成したいと思います。 EntityにEmbeddedIdを定義しています:
@Entity
@Table(name="TB_INTERFASES")
public class Interfase implements Serializable {
@EmbeddedId
private InterfaseId id;
}
@Embeddable
public class InterfaseId implements Serializable {
@Column(name="CLASE")
private String clase;
}
そして私がやろうとしている基準クエリは:
CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
CriteriaQuery<Interfase> criteriaQuery = criteriaBuilder.createQuery(Interfase.class);
Root<Interfase> entity = criteriaQuery.from(Interfase.class);
criteriaQuery.where(
criteriaBuilder.equal(entity.get("clase"), "Clase"),
);
しかし、これはIllegalArgumentExceptionをスローしています。
Java.lang.IllegalArgumentException: Not an managed type: class InterfaseId
私もこのクエリを試してみました:
Root<Interfase> entity = criteriaQuery.from(Interfase.class);
criteriaQuery.where(
criteriaBuilder.equal(entity.get("id").get("clase"), "Clase"),
);
これも….
Root<Interfase> entity = criteriaQuery.from(Interfase.class);
criteriaQuery.where(
criteriaBuilder.equal(entity.get("id.clase", "Clase"),
);
運がない。だから私の質問は、クラスがEmbeddedおよびEmbeddedIdアノテーションを使用しているときに、どのように基準を使用してクエリを作成できるかということです。
ありがとう!マウロ。
Embeddable
の属性にアクセスするには、パスナビゲーションを使用する必要があります。以下はJPA 2.0仕様の例です(静的メタモデルを使用)。
6.5.5パスナビゲーション
...
次の例では、
ContactInfo
はアドレスと電話のセットで構成される組み込み可能なクラスです。Phone
はエンティティです。CriteriaQuery<Vendor> q = cb.createQuery(Vendor.class); Root<Employee> emp = q.from(Employee.class); Join<ContactInfo, Phone> phone = emp.join(Employee_.contactInfo).join(ContactInfo_.phones); q.where(cb.equal(emp.get(Employee_.contactInfo) .get(ContactInfo_.address) .get(Address_.zipcode), "95054")) .select(phone.get(Phone_.vendor));
次のJava永続クエリ言語クエリは同等です。
SELECT p.vendor FROM Employee e JOIN e.contactInfo.phones p WHERE e.contactInfo.address.zipcode = '95054'
したがって、あなたの場合、次のようなものが必要になると思います:
criteriaBuilder.equal(entity.get("id").get("clase"), "Referencia 111")
pdate:提供されたエンティティをHibernate EntityManager 3.5.6と次のクエリでテストしました。
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Interfase> criteria = builder.createQuery(Interfase.class);
Root<Interfase> interfaseRoot = criteria.from(Interfase.class);
criteria.select(interfaseRoot);
criteria.where(builder.equal(interfaseRoot.get("id").get("clase"),
"Referencia 111"));
List<Interfase> interfases = em.createQuery(criteria).getResultList();
正常に実行され、次のSQLが生成されます。
17:20:26.893 [main] DEBUG org.hibernate.SQL- select interfase0_.CLASE as CLASE31_ from TB_INTERFASES interfase0_ where interfase0_.CLASE =? 17:20:26.895 [main] TRACE org.hibernate.type.StringType-「Referencia 111」をパラメータにバインド:1
期待どおりに動作します。
metamodel
クラスをコピーして、エンティティが保存されているのと同じフォルダに貼り付けてください(NetBeans 8.2では、これらは自動的に生成され、エンティティの名前は同じですが、末尾にアンダースコアが付いています。 Interfase_
およびInterfaseId_
)。
metamodel
クラスのインポートを強制するInterfase_
およびInterfaseId_
をクリックして、目的のフィールドを参照します。
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Interfase> criteria = builder.createQuery(Interfase.class);
Root<Interfase> interfaseRoot = criteria.from(Interfase.class);
criteria.select(interfaseRoot);
criteria.where(builder.equal(interfaseRoot.get(Interfase_.id).get(InterfaseId_.clase),"Referencia 111"));
List<Interfase> interfases = em.createQuery(criteria).getResultList();
古い質問ですが、とにかく...
別の非常にシンプルなソリューションは
InterfaseId id = new InterfaseId();
id.setClase("Clase");
Interfase found = em.find(id);
あなたが尋ねた以外の何かをしようとする場合を除いて、これはそれを行う「正気な」方法です。 idに対するクエリは、最大1つの結果を返します。