After summarizing the situation of entities:
Collision → CollisionStatus ↔ CollisionWorkgroup (object merging) → Workgroup
Collision.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: (interest class, see below)
@Entity
@Table( name = "..." )
public class CollisionStatus
{
...
@OneToMany( mappedBy = "collisionStatus", fetch = FetchType.LAZY )
@MapKeyColumn( name = "CLIENT_ID", insertable = false, updatable = false )
private Map<Long, CollisionWorkgroup> collisionWorkgroups;
...
}
CollisionWorkgroup.java: (attach an entity / table between CollisionStatusand Workgroup, with PK = [CollisionStatusId, ClientId], both types Long)
@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: (connect PK class object)
@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 : (actually not very interesting, just used to compare clientId in query criteria)
@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.
, . , , ( ), .
as-is , , /.
, , . .
SO:
JPA CriteriaBuilder , ,
:
@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<?>>
, , a Map Collection.
:
Map JPA, API- Criteria?