После referenciation ситуации лиц:JPA CriteriaBuilder генерировать запрос, где карта пуста, используя @MapKeyColumn
Столкновение -> CollisionStatus < -> CollisionWorkgroup (присоединиться к организации) -> 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: (класс интереса, смотри ниже)
@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: (присоединиться сущность/таблица между CollisionStatus
и Workgroup
, с PK = [CollisionStatusId, ClientID], оба типа 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: (присоединиться предприятие Класс 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: (на самом деле не очень интересно, просто используется для сравнения 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
,
Это означает, что каждый клиент может связывать ровно одну рабочую группу с сущностью статуса столкновения. Каждый пользователь, подключенный к системе, видит только один из своих клиентов (каждый пользователь принадлежит одному клиенту), но другие не должны быть видимыми в пользовательском интерфейсе.
При выполнении запроса as-is любые состояния столкновений, с которыми несколько клиентов установили рабочую группу, дают дополнительные результаты в наших результатах таблицы данных/запроса.
Это имеет смысл, поэтому мне нужно добавить некоторые пользовательские предикаты к запросу в , чтобы генерировать записи, содержащие идентификатор клиента текущего пользователя, связанный с. Отображение записей других клиентов неверно.
Я нашел это на 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
является n от подкласса Collection
.
Q:
Как вы тест на пустой Map
в JPA, используя критерии API?
FWIW - https://hibernate.atlassian.net/browse/HHH-11225 –
Спасибо Стив. Я хотел бы сообщить RFE экспертной группе JPA. Не могли бы вы доставить меня туда, где я могу это сделать, поскольку вы являетесь частью команды экспертов? – Kawu
Существует https://java.net/jira/browse/JPA_SPEC, но не было решено, что произойдет с планируемым списком java.net. –