我有一個表的字符串值爲它所指向的實體的條形碼。不幸的是,它不是一個外鍵,它只是一個字符串,所以不存在映射。這使得聯合操作變得困難。我想知道如何將這個對象加入另一個沒有定義關係的表中。例如:CriteriaQuery加入字符串值
@Entity
@Table(name = "TblSample", schema = SCHEMA, catalog = CATALOG)
public class Sample {
@Id
@Column(name = "id", nullable = false)
private int id;
@Column(name = "barcodeEntity", nullable = false)
private String barcodeEntity;
@OneToOne
@JoinColumn(name = "barcodeContainer", nullable = false)
private Container container;
...
}
@Entity
@Table(name = "TblSoil", schema = SCHEMA, catalog = CATALOG)
public class Soil {
@Column(name = "barcode", nullable = false)
private String barcode;
@Column(name = "name", nullable = false)
private String name;
...
}
@Entity
@Table(name = "TblLeaf", schema = SCHEMA, catalog = CATALOG)
public class Leaf {
@Column(name = "barcode", nullable = false)
private String barcode;
@Column(name = "name", nullable = false)
private String name;
...
}
@Entity
@Table(name = "TblContainer", schema = SCHEMA, catalog = CATALOG)
public class Container {
@Column(name = "barcode", nullable = false)
private String barcode;
@Column(name = "name", nullable = false)
private String name;
@Column(name = "location", nullable = false)
private String location;
...
}
所以,我想用一個CriteriaQuery中可以返回所有的樣品和加入的,它是取自實體。我已經開始編寫它,但是當我試圖找出如何去做時,我陷入了困境。在SQL它想是這樣的:
SELECT TOP 100
sample.Id
, sample.barcodeEntity
, leaf.name
, soil.name
, sample.barcodeContainer
, container.name
, container.location
FROM TblSample sample
LEFT JOIN TblSoil leaf on
soil.barcode = sample.barcodeEntity
LEFT JOIN TblLeaf leaf on
leaf.barcode = sample.barcodeEntity
JOIN TblContainer container on
container.barcode = sample.barcodeContainer
我想,相關的JPA CriteriaQuery中會是這個樣子:
public void findSamples(Map<String, String> filterCriteria) {
final CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
final CriteriaQuery<SampleLocation> query = builder.createQuery(SampleLocation.class);
final Root<Sample> derivation = query.from(Sample.class);
// Note that the next two lines don't work
final Join<Leaf> joinOnLeaf = derivation.join(Sample_.barcodeEntity, JoinType.LEFT);
final Join<Soil> joinOnSoil = derivation.join(Sample_.barcodeEntity, JoinType.LEFT);
final Join<Container> joinOnContainer = derivation.join(Sample_.barcodeContainer);
CompoundSelection<SampleLocation> cSelect =
builder.construct(SampleLocation.class, sample.Id, sample.entitybarcode, joinOnLeaf.get(Leaf_.name), joinOnLeaf.get(Soil_.name), sample.barcodeContainer, joinOnContainer.get(Container_.name), joinOnContainer.get(Container_.location));
query.select(cSelect);
TypedQuery<SampleLocation> typedQuery = entityManager.createQuery(query);
typedQuery.setMaxResults(100);
return typedQuery.getResults();
}
任何想法如何,我可以執行左連接操作?我無法根據CriteriaQuery API做出決定。看起來像是應該存在的東西。
老實說,一旦查詢得到這個複雜度,我會訴諸於HQL(假設你使用的是Hibernate ...) – 2013-02-25 13:56:59
作爲最後的手段,我可能會試試這個。不過,我寧願不要因爲它不安全。我們大多數是Java開發人員,所以我們從這個角度來看更適合執行數據庫工作。說了這也許是這些特殊情況之一。如果我無法使用JPA,那麼我認爲我們將開發一個獨立的項目來執行復雜的查詢(比如這個),以便將其與代碼庫的其餘部分隔離開來。一旦將SQL引入代碼庫中,維護起來可能會變得非常困難(正如我發現的那樣)。 – Craig 2013-02-26 07:06:14