gpt4 book ai didi

java - JPA CriteriaBuilder 使用 @MapKeyColumn 生成 Map 为空的查询

转载 作者:搜寻专家 更新时间:2023-11-01 03:18:13 24 4
gpt4 key购买 nike

实体引用情况如下:

Collision -> CollisionStatus <-> CollisionWorkgroup(加入实体) -> Workgroup

碰撞.java:

@Entity
@Table( name = "..." )
public class Collision
{
...

@OneToOne( fetch = FetchType.EAGER, optional = false )
@JoinColumn( name = "CSSTATE_ID", referencedColumnName = "CSSTATE_ID" )
private CollisionStatus collisionStatus;

...
}

CollisionStatus.java:(感兴趣的类,见下文)

@Entity
@Table( name = "..." )
public class CollisionStatus
{
...

// THIS IS THE MAPPING OF INTEREST:
@OneToMany( mappedBy = "collisionStatus", fetch = FetchType.LAZY )
@MapKeyColumn( name = "CLIENT_ID", insertable = false, updatable = false )
private Map<Long, CollisionWorkgroup> collisionWorkgroups;

...
}

CollisionWorkgroup.java:(在 CollisionStatusWorkgroup 之间加入实体/表,PK=[CollisionStatusId, ClientId],两者类型 )

@Entity
@Table( name = "..." )
public class CollisionWorkgroup
{
@EmbeddedId
protected CollisionWorkgroupEmbeddedPK pk;

@MapsId( "collisionStatusId" )
@JoinColumn( name = "CSSTATE_ID", referencedColumnName = "CSSTATE_ID" )
private CollisionStatus collisionStatus;

@MapsId( "clientId" )
@ManyToOne
@JoinColumn( name = "CLIENT_ID", referencedColumnName = "CLIENT_ID" )
private Client client;

@ManyToOne( fetch = FetchType.LAZY, optional = false )
@JoinColumn( name = "WORKGROUP_ID", referencedColumnName = "WORKGROUP_ID" )
private Workgroup workgroup;

...
}

CollisionWorkgroupEmbeddedPK.java:(加入实体PK类)

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

@Column( name = "CSSTATE_ID" )
private Long collisionStatusId;

@Column( name = "CLIENT_ID" )
private Long clientId;

...
}

Workgroup.java:(其实不是很感兴趣,只是用来比较criteria查询中的clientId)

@Entity
@Table( name = "..." )
public class Workgroup
{
@Column( name = "CLIENT_ID", insertable = false, updatable = false )
private Long clientId;

@ManyToOne( fetch = FetchType.EAGER, optional = false )
@JoinColumn( name = "CLIENT_ID", referencedColumnName = "CLIENT_ID" )
private Client client;

...
}

这里有趣的映射是从 CollisionStatus 到加入实体 CollisionWorkgroup 以使用 @MapKeyColumn 连接工作组。

这意味着,每个客户端都可以将一个工作组与碰撞的状态实体关联起来。每个登录系统的用户只能看到来自其客户端的一个(每个用户属于一个客户端),但其他用户在 UI 上是不可见的。

按原样执行查询时,多个客户端设置工作组的任何冲突状态都会在我们的数据表/查询结果中产生额外的结果。

这是有道理的,所以我需要向查询添加一些自定义谓词以仅生成与当前用户的客户端 ID 相关联的条目。显示其他客户端的条目是错误的。

我在 SO 上找到了这个:

Using JPA CriteriaBuilder to generate query where attribute is either in a list or is empty

我试过代码:

@Override
protected List<Predicate> createCustomPredicates( CriteriaBuilder builder, From<?, ?> root )
{
List<Predicate> predicates = new ArrayList<>();

Long clientId = this.sessionHelper.getCurrentClientId();
Join<Collision, CollisionStatus> collisionStatus = root.join( "collisionStatus" );
MapJoin<CollisionStatus, Long, CollisionWorkgroup> collisionWorkgroups = collisionStatus.<CollisionStatus, Long, CollisionWorkgroup>joinMap( "collisionWorkgroups", JoinType.LEFT );
predicates.add( builder.and( builder.or( builder.isEmpty( collisionWorkgroups ),
builder.equal( collisionWorkgroups.<String>get( "workgroup" ).<String>get( "clientId" ), clientId ) ) ) );

...
}

这在 builder.isEmpty( 说:

Bound mismatch: The generic method isEmpty(Expression<C>) of type CriteriaBuilder
is not applicable for the arguments (MapJoin<CollisionStatus,Long,CollisionWorkgroup>).
The inferred type CollisionWorkgroup is not a valid substitute for the bounded
parameter <C extends Collection<?>>

显然,问题在于 Map 不是 Collection 的子类。

问:

如何使用 Criteria API 在 JPA 中测试空 Map

最佳答案

是的,因为 Map 不是 Collection。就 Criteria API 而言,JPA 仅根据 Collection 定义 IS_EMPTY 谓词。由于这一点以及关联的 CriteriaBuilder 方法签名,您将无法通过 JPA 的 CriteriaBuilder 执行此操作。

真的 JPA 应该为该方法添加一个重载:

// existing method
<C extends Collection<?>> Predicate isEmpty(Expression<C> collection);
// overload
<C extends Map<?>> Predicate isEmpty(Expression<C> map);

但是 JPQL 应该可以工作。

关于java - JPA CriteriaBuilder 使用 @MapKeyColumn 生成 Map 为空的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40259448/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com