JPA named query match a list of tuples in IN clause

≯℡__Kan透↙ 提交于 2019-12-10 03:34:00

问题


spring data jpa 1.4.3 with Oracle 11g.

I have an entity like this:

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

I am using (value, linkType) as a composite index. For a given list of (v, t) tuples, we need to select all the records in the DB so that value = v, linkType = t.

Basically, I want to build this query:

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

where the list in the IN clause is passed in as a param.

Since we're working with a large volume of data, it would be very undesirable to query for the tuples one by one.

In my repository I've tried this:

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

where keys is a list of (lists of length 2). This gets me ORA_00920: invalid relational operator.

Is there any way to make this work using a named query? Or do I have to resort to native sql?

Thanks for your help.


回答1:


The answer is too late, but maybe some1 else has the same problem. This is one of my working examples. Here I need to search for all entries that match a given composite key:

The entity....

@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
}

The PK class....

@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 by....

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

where....

articlePks is List<ArticlePk>.



来源:https://stackoverflow.com/questions/23832551/jpa-named-query-match-a-list-of-tuples-in-in-clause

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!