2014-10-06 101 views
3

我是relativley關係數據庫的新手,我在創建查詢時遇到了一些問題。首先,我想盡快解釋這種情況。我有幾個實體類。他們全部延伸AbstractEntityEntityProperty。所以實體可以擁有屬性和屬性擁有實體,所以存在雙向關係。
現在讓我們假設ConcreteEntity延伸AbstractEntity,我想要創建像這樣的查詢:獲取所有類型爲ConcreteEntity的實體,它至少在屬性名稱中包含給定列表propertyNames。到現在爲止,我有以下的工作條件查詢:條件API:按類類型過濾

CriteriaQuery<AbstractEntity> cq = cb.createQuery(AbstractEntity.class); 
Root<EntityProperty> property = cq.from(EntityProperty.class); 
Join<EntityProperty, AbstractEntity> entity = property.join(EntityProperty_.owningEntities); 
cq.where(property.get(EntityProperty_.name).in((Object[]) propertyNames)); 
cq.select(entity); 

但現在我只想ConcreteEntity類型的實體。我怎麼能做到這一點? 在JPQL中我寫了「SELECT實體FROM EntityProperty屬性JOIN property.owningEntities實體」,這裏我也不知道如何以只返回特定類型的方式編寫它...

感謝您提前給出解答!

編輯:移動第二個問題,以criteria query: indistinct result lists併除去在代碼(沒有工作)

+0

如果你有這個查詢參數化使用泛型?然後你可以說在編譯時需要AbstractEntity或者ConcreteEntity(不知道這是否合理) – Leo 2014-10-06 22:55:03

+0

當我將實體定義爲root時,我可以這樣做。然後我可以明確地定義這個班級。這裏的問題是我通過配件屬性的owningEntities屬性來訪問實體。並且該屬性具有List 類型。 – Jogi 2014-10-06 23:02:11

回答

1

我發現到目前爲止,唯一的方法不同的是,藉助每一類所得到的條件的值創建一個枚舉查詢是

CriteriaQuery<AbstractEntity> cq = cb.createQuery(AbstractEntity.class); 
Root<EntityProperty> property = cq.from(EntityProperty.class); 
SetJoin<EntityProperty, AbstractEntity> entity = 
       property.join(EntityProperty_.owningEntities); 
cq.where(property.get(EntityProperty_.name).in((Object[]) propertyNames), 
       entity.get(AbstractEntity_.entityType).in(suitableSubTypes)); 
cq.select(entity); 
List<AbstractEntity> resultList = em.createQuery(cq).getResultList(); 

如您所見,每個實體現在都具有屬性entityType。我也必須每次創建合適的適配子類型。另一個問題是返回的類型是List<AbstractEntity>。我想要的是一個方法簽名一樣

public static <T extends AbstractEntity> List<T> 
       getEntities(Class<T> entityClass, String... propertyNames) 

但現在我有

public static List<AbstractEntity> 
       getEntities(Collection<AbstractEntityType> suitableSubTypes, 
       String... propertyNames) 

所以我還是希望存在一個更好的解決辦法...

2

我知道這是個老問題但爲了防止有人絆倒同樣的問題,這裏是如何解決的。 您可以通過實體類型像這樣輕鬆過濾:

Predicate p = cb.equal(entity.type(), cb.literal(ConcreteEntity.class)); 

其中實體可以是一個路徑(根和加入在內),CB是CriteriaBuilder對象。所以在你的情況下,它會是這樣的:

CriteriaQuery<AbstractEntity> cq = cb.createQuery(AbstractEntity.class); 
Root<EntityProperty> property = cq.from(EntityProperty.class); 
Join<EntityProperty, AbstractEntity> entity = property.join(EntityProperty_.owningEntities); 
cq.where(cb.and(
    property.get(EntityProperty_.name).in((Object[]) propertyNames), 
    cb.equal(entity.type(), cb.literal.ConcreteEntity.class) 
)); 
cq.select(entity);