2014-05-23 11 views
5

Frühjahr Daten jpa 1.4.3 mit Oracle 11g.JPA benannte Abfrage entspricht einer Liste von Tupeln in IN-Klausel

Ich habe ein Unternehmen wie folgt aus:

class LinkRecord { 
    String value; 
    int linkType; 
    ... 
} 

I (Wert, link) verwende als Composite-Index. Für eine gegebene Liste von (v, t) Tupeln müssen wir alle Datensätze im DB so auswählen, dass value = v, linkType = t.

Grundsätzlich möchte ich diese Abfrage erstellen:

SELECT * FROM LINK_RECORD WHERE (VALUE, LINK_TYPE) IN (('value1', 0), ('value2', 25), ...) 

, wo die Liste in der IN-Klausel wird als param eingeleitet.

Da wir mit einer großen Datenmenge arbeiten, wäre es sehr unerwünscht, die Tupel nacheinander abzufragen.

In meinem Repository Ich habe dies versucht:

@Query("select r from LinkRecord r where (r.value, r.linkType) in :keys") 
List<LinkRecord> findByValueAndType(@Param("keys")List<List<Object>> keys); 

wo Schlüssel ist eine Liste von (Listen der Länge 2). Das bringt mich zu ORA_00920: ungültiger relationaler Operator.

Gibt es eine Möglichkeit, dies mit einer benannten Abfrage zu machen? Oder muss ich auf native sql zurückgreifen?

Danke für Ihre Hilfe.

Antwort

0

Die Antwort ist zu spät, aber vielleicht hat jemand anderes das gleiche Problem. Dies ist eines meiner Arbeitsbeispiele. Hier muss ich für alle Einträge suchen, die einen bestimmten zusammengesetzten Schlüssel entsprechen:

Das Unternehmen ....

@Entity 
@NamedQueries({ 
    @NamedQuery(name = "Article.findByIdAndAccessId", query = "SELECT a FROM Article a WHERE a.articlePk IN (:articlePks) ORDER BY a.articlePk.article") 
}) 
@Table(name = "ARTICLE") 
public class Article implements Serializable 
{ 
    private static final long serialVersionUID = 1L; 

    @EmbeddedId 
    private ArticlePk articlePk = new ArticlePk(); 

    @Column(name = "art_amount") 
    private Float amount; 

    @Column(name = "art_unit") 
    private String unit; 

    public Article() 
    { 
    } 

    //more code 
} 

Die PK-Klasse ....

@Embeddable 
public class ArticlePk implements Serializable 
{ 
    private static final long serialVersionUID = 1L; 

    @Column(name = "art_article") 
    private String article; 

    @Column(name = "art_acc_identifier") 
    private Long identifier; 

    public ArticlePk() 
    { 
    } 

    public ArticlePk(String article, Long identifier) 
    { 
     this.article = article; 
     this.identifier = identifier; 
    } 

    @Override 
    public boolean equals(Object other) 
    { 
     if (this == other) 
     { 
      return true; 
     } 
     if (!(other instanceof ArticlePk)) 
     { 
      return false; 
     } 

     ArticlePk castOther = (ArticlePk)other; 
     return this.article.equals(castOther.article) && this.identifier.equals(castOther.identifier); 
    } 

    @Override 
    public int hashCode() 
    { 
     final int prime = 31; 
     int hash = 17; 
     hash = hash * prime + this.article.hashCode(); 
     hash = hash * prime + this.identifier.hashCode(); 

     return hash; 
    } 

    //more code 
} 

Invocation von .. ..

TypedQuery<Article> queryArticle = entityManager.createNamedQuery("Article.findByIdAndAccessId", Article.class); 
queryArticle.setParameter("articlePks", articlePks); 
List<Article> articles = queryArticle.getResultList(); 

wo ....

articlePks ist List<ArticlePk>.

Verwandte Themen