Итак, я написал следующий запрос для использования в Spring JpaRespository:
private const val SEARCH =
"SELECT vf " +
"FROM VideoFile vf " +
"LEFT JOIN vf.stars st " +
"LEFT JOIN vf.categories c " +
"LEFT JOIN vf.series se " +
"WHERE (:searchText IS NULL OR (" +
"vf.fileName LIKE :searchText OR vf.displayName LIKE :searchText OR vf.description LIKE :searchText)) " +
"AND (:seriesId IS NULL OR se.seriesId = :seriesId) " +
"AND (:starId IS NULL OR st.starId = :starId) " +
"AND (:categoryId IS NULL OR c.categoryId = :categoryId)"
Это основано на запросе SQL, который я тестировал ранее, но написал для использования JPQL. Я собираюсь включить мою сущность (Kotlin) ниже, так что то, что я собираюсь объяснить, будет иметь больше смысла:
@Entity
@Table(name = "video_files")
data class VideoFile(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var fileId: Long = 0,
@Column(unique = true)
var fileName: String = "",
var displayName: String = "",
var description: String = "",
var lastModified: LocalDateTime = DEFAULT_TIMESTAMP,
@JsonIgnore
var lastScanTimestamp: LocalDateTime = DEFAULT_TIMESTAMP,
@Column(columnDefinition = "int default 0")
var viewCount: Int = 0,
@ManyToMany (fetch = FetchType.EAGER)
@JoinTable(name = "file_categories",
joinColumns = [JoinColumn(name = "file_id")],
inverseJoinColumns = [JoinColumn(name = "category_id")])
var categories: Set<Category> = HashSet(),
@ManyToMany (fetch = FetchType.EAGER)
@JoinTable(name = "file_series",
joinColumns = [JoinColumn(name = "file_id")],
inverseJoinColumns = [JoinColumn(name = "series_id")])
var series: Set<Series> = HashSet(),
@ManyToMany (fetch = FetchType.EAGER)
@JoinTable(name = "file_stars",
joinColumns = [JoinColumn(name = "file_id")],
inverseJoinColumns = [JoinColumn(name = "star_id")])
var stars: Set<Star> = HashSet()
)
Итак, моя сущность VideoFile имеет отношение ManyToMany с сущностями Category, Series и Star. Запрос, который я пишу, является попыткой получить все видеофайлы, объединенные с определенными категориями, сериями, звездами и т. Д.
Запрос, который у меня сейчас есть, возвращает дубликаты записей, я полагаю, из-за левых соединений. Поскольку видеофайл совпадает с несколькими категориями, одна и та же запись возвращается несколько раз.
Я хорошо разбираюсь в SQL, я все еще новичок в JPQL. Я был бы признателен за помощь в рефакторинге, чтобы он просто фильтровал видеофайлы по объединенным объектам, а не возвращал дополнительные записи.
Спасибо.