IN子句中包含JPA标准中的复合主键 [英] IN clause with a composite primary key in JPA criteria

查看:464
本文介绍了IN子句中包含JPA标准中的复合主键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在MySQL中有一个名为 group_table 的表,只有两列 user_group_id group_id (它们都是 VARCHAR 类型)。这两个列一起构成一个复合主键。

我需要使用子选择 IN()

  @Override 
@SuppressWarnings($ c $> $ c>}根据传递给查询的值列表选择行。

unchecked)
public List< GroupTable> getList(List< GroupTable> list)
{
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery< GroupTable> CriteriaQuery中= criteriaBuilder.createQuery(GroupTable.class);
Root< GroupTable> root = criteriaQuery.from(entityManager.getMetamodel()。entity(GroupTable.class));
criteriaQuery.where(root.in(list));
返回entityManager.createQuery(criteriaQuery).getResultList();
}

执行产生以下查询。

SELECT group_id,
user_group_id
FROM projectdb.group_table
WHERE((?,?)IN ((?,?),(?,?)))

/ *绑定参数* /
bind => [null,null,ROLE_AAA,aaa,ROLE_BBB,aaa]

请注意,前两个参数关于组合键本身是 null 。它们应该分别是 user_group_id group_id



是不是在参数列表中被替换?






虽然我不想在表格中形成复合主键,这对于我用于身份验证的JAAS来说可能是必需的。



在这种情况下,查询返回的是与从实际上不需要的数据库。我真的需要这个查询删除多行。 试试这个

  CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 
CriteriaQuery< GroupTable> cq = cb.createQuery(GroupTable.class);
Root< GroupTable> r = cq.from(GroupTable.class);
表达式< EntityPK> exp = r.get(id); // EntityPK是您的主要组合键类,id是GroupTable实体中主键的属性名称
谓词谓词= exp.in(list);
cq.select(r).where(predicate);

entityManager.createQuery(cq).getResultList();

我有下面的表格,结构如下

<
col1 integer not null,
description varchar(255),
主键(
) col1,col2)

以下是实体和复合键类

  @Entity 
公共类EntityA实现Serializable {

@EmbeddedId
私人EntityPK ID;
私有字符串描述;

// getters,setteres
...........................
.. ..........................


}


@Embeddable
public class EntityPK实现Serializable {

private int col1;
private int col2;

// getters,setters,hashcode,equals等

我的测试代码是

  CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery< EntityA> cq = cb.createQuery(EntityA.class);
Root< EntityA> r = cq.from(EntityA.class);
表达式< EntityPK> exp = r.get(id);
谓词谓词= exp.in(list);
cq.select(r).where(predicate);
em.createQuery(cq).getResultList();

结果SQL是

 选择
entitya0_.col1如col1_0_,
entitya0_.col2如col2_0_,
entitya0_.description从$ b $ descript3_0_
b EntityA entitya0_
其中
entitya0_.col1 =?
和entitya0_.col2 =?
或者entitya0_.col1 =?
和entitya0_.col2 =?
或者entitya0_.col1 =?
和entitya0_.col2 =?


I have a table named group_table in MySQL with only two columns user_group_id and group_id (both of them are of type VARCHAR). Both of these columns together form a composite primary key.

I need to execute a statement using a sub-select IN() to select rows based on a list of values passed to the query.

@Override
@SuppressWarnings("unchecked")
public List<GroupTable> getList(List<GroupTable> list)
{
    CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
    CriteriaQuery<GroupTable> criteriaQuery=criteriaBuilder.createQuery(GroupTable.class);
    Root<GroupTable> root = criteriaQuery.from(entityManager.getMetamodel().entity(GroupTable.class));
    criteriaQuery.where(root.in(list));
    return entityManager.createQuery(criteriaQuery).getResultList();
}

The implementation produces the following query.

SELECT group_id, 
       user_group_id 
FROM   projectdb.group_table 
WHERE  ((?, ?) IN ((?, ?), (?, ?))) 

/*Binding parameters.*/
bind => [null, null, ROLE_AAA, aaa, ROLE_BBB, aaa]

Please notice that the first two parameters which are about the composite key itself are null. They should be user_group_id and group_id respectively.

Why are they not substituted in the parameter list?


While I'm not interested in forming a composite primary key in a table, this is (likely) mandatory for JAAS I'm using for authentication.

In this scenario, the query returns the same list as it is supplied from the database which is needless in reality. I actually need this query for deletion of multiple rows.

解决方案

Try this

        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<GroupTable> cq = cb.createQuery(GroupTable.class);
        Root<GroupTable> r = cq.from(GroupTable.class);
        Expression<EntityPK> exp = r.get("id"); //EntityPK is your primary composite key class and id is the property name of primary key in GroupTable entity
        Predicate predicate = exp.in(list);
        cq.select(r).where(predicate);

        entityManager.createQuery(cq).getResultList();

I have a following table with below structure

create table EntityA (
        col1 integer not null,
        col2 integer not null,
        description varchar(255),
        primary key (col1, col2)
    )

Following are the entity and composite key classes

@Entity
public class EntityA implements Serializable {

    @EmbeddedId
    private EntityPK id;
    private String description;

// getters, setteres    
    ...........................
    ............................


    }


@Embeddable
public class EntityPK implements Serializable {

    private int col1;
    private int col2;

// getters, setters, hashcode, equals etc

My test code is

 CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<EntityA> cq = cb.createQuery(EntityA.class);
        Root<EntityA> r = cq.from(EntityA.class);
        Expression<EntityPK> exp = r.get("id");
        Predicate predicate = exp.in(list);
        cq.select(r).where(predicate);
        em.createQuery(cq).getResultList();

The resulting SQL is

select
        entitya0_.col1 as col1_0_,
        entitya0_.col2 as col2_0_,
        entitya0_.description as descript3_0_ 
    from
        EntityA entitya0_ 
    where
        entitya0_.col1=? 
        and entitya0_.col2=? 
        or entitya0_.col1=? 
        and entitya0_.col2=? 
        or entitya0_.col1=? 
        and entitya0_.col2=?

这篇关于IN子句中包含JPA标准中的复合主键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆