JPA - где условие не работает на связанный объект - PullRequest
0 голосов
/ 12 февраля 2020

Я пытаюсь применить условие where к связанной сущности, но набор результатов содержит все данные связанной сущности. Похоже, фильтр игнорируется. У меня есть следующие объекты:

Аудит объекта:

@Entity
@Table(name = "entity_audit")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@org.springframework.data.elasticsearch.annotations.Document(indexName = "entityaudit")
public class EntityAudit implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@org.springframework.data.elasticsearch.annotations.Field(type = FieldType.Keyword)
private Long id;

@NotNull
@Column(name = "entity_id", nullable = false)
private Long entityId;

@NotNull
@Column(name = "entity_class_name", nullable = false)
private String entityClassName;

@NotNull
@Column(name = "entity_name", nullable = false)
private String entityName;

@NotNull
@Enumerated(EnumType.STRING)
@Column(name = "action_type", nullable = false)
private EntityAuditType actionType;

@NotNull
@Column(name = "timestamp", nullable = false)
private Instant timestamp;

@NotNull
@Column(name = "user", nullable = false)
private String user;

@NotNull
@Column(name = "transaction_uuid", nullable = false)
private String transactionUuid;

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "entity_audit_id")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<EntityAuditUpdateData> entityAuditUpdateData = new HashSet<>();

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "entity_audit_id")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<EntityAuditStatus> entityAuditStatuses = new HashSet<>();

Getters and setters...

Статус аудита объекта

@Entity
@Table(name = "entity_audit_status")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@org.springframework.data.elasticsearch.annotations.Document(indexName = "entityauditstatus")
public class EntityAuditStatus implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@org.springframework.data.elasticsearch.annotations.Field(type = FieldType.Keyword)
private Long id;

@NotNull
@Column(name = "user_login", nullable = false)
private String userLogin;

@NotNull
@Column(name = "jhi_read", nullable = false)
private Boolean read;

@ManyToOne
private EntityAudit entityAudit;

Getters and setters...

Я пытаюсь выполнить этот запрос:

@Query("select distinct entityAudit from EntityAudit entityAudit " +
    "join entityAudit.entityAuditStatuses entityAuditStatus " +
    "where entityAuditStatus.userLogin =:userLogin " +
    "order by entityAudit.timestamp desc")
Page<EntityAudit> retireveAllByUserLogin(@Param(value = "userLogin") String userLogin, Pageable pageable);

Но когда я получаю данные, EntityAuditStatuses не фильтруются. Я не могу понять, где проблема. Спасибо.

1 Ответ

0 голосов
/ 12 февраля 2020

Примечание: я удалил свойство date из минимального воспроизводимого примера.

Используйте left join fetch вместо left join, чтобы убедиться, что зависимые entityAuditStatuses извлекаются как часть самого запроса соединения, а не как несколько запросов после нахождения entityAudit. А так как результат должен быть разбит на страницы, необходимо указать дополнительный countQuery (без извлечения). Рабочий запрос -

@Query(value = "select entityAudit from EntityAudit entityAudit " +
            "left join fetch entityAudit.entityAuditStatuses entityAuditStatus " +
            "where entityAuditStatus.userLogin = :userLogin ",
       countQuery = "select entityAudit from EntityAudit entityAudit " +
            "left join entityAudit.entityAuditStatuses entityAuditStatus " +
            "where entityAuditStatus.userLogin = :userLogin ")

Без left join fetch генерируются три запроса - один, который выбирает entityAuditId 1 (на основе userLogin 1), а затем еще два для выборки entityAuditStatuses (только из таблицы entity_audit_status) без объединения) с указанием entityAuditId 1.

. Поэтому, когда вы запрашиваете userLogin = '1' - вы получаете EntityAudit 1, который приносит с собой - entityAuditStatus 1 - entityAuditStatus 3 (который имеет userLogin = ' 2 ')

После добавления left join fetch существует только один запрос, использующий соединение согласно определенным отношениям сущностей. Таким образом, результаты правильно получены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...