JPA:加入和排序 by/limit 约束 child table 的 OneToMany 关系与流利或 @Query
JPA: Join and order by/limit constraint on child table of OneToMany relation with fluent or @Query
给定以下模型:
@Entity
open class Parent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
open val id: Long? = null
@OneToMany(cascade = [CascadeType.ALL])
@JoinColumn(name = "parent_id")
@OrderColumn(name = "version")
private var children: MutableList<Child> = mutableListOf()
fun addChild(child: Child) {
child.parent = this
children.add(child)
}
fun getChildPosition(child: Child): Int {
return children.indexOf(child)
}
}
@Entity
open class Child {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
open val id: Long? = null
@ManyToOne
@JoinColumn(name = "parent_id")
open var parent: Parent? = null
@Column(nullable = false)
open var data: String? = null
@Column(name = "version")
open var version: Int? = null
@PrePersist
@PreUpdate
private fun prepareVersion() {
if (parent != null) {
version = parent?.getChildPosition(this)
}
}
}
interface MyProjection {
// parent.id, child.id, child.version, child.data
}
@Repository
interface ParentRepository : JpaRepository<Parent, UUID> {
@Query("?")
fun findWithLatestChild(id: Long?): MyProjection?
}
是否可以使用 JPA 方法命名约定或 JPQL 查询来执行以下操作:
- 在 parent.id 上加入 parent 和 child。
- 在版本 (desc) 上订购 children 并将结果限制为 1。
- 投影 properties/columns 如上面的模拟投影界面中所述。
更新:
如果这不可行,以下本机查询描述了我的意图:
select p.id,c.* from parent p join child c on p.id = c.parent_id
where p.id = :parentId
order by c.version desc
limit 1
因此您可以创建这样的查询:
@Query("select new packagename.MyProjection(c.parent.id, c.id, c.version, c.data ) " +
"from Child where c.parent.id = :parentId order by c.version desc")
fun findWithLatestChild(id: Long?, pageable: Pageable): MyProjection?
然后用 PageRequest 调用它以将结果限制为 1
findWithLatestChild(PageRequest.of(0,1));
给定以下模型:
@Entity
open class Parent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
open val id: Long? = null
@OneToMany(cascade = [CascadeType.ALL])
@JoinColumn(name = "parent_id")
@OrderColumn(name = "version")
private var children: MutableList<Child> = mutableListOf()
fun addChild(child: Child) {
child.parent = this
children.add(child)
}
fun getChildPosition(child: Child): Int {
return children.indexOf(child)
}
}
@Entity
open class Child {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
open val id: Long? = null
@ManyToOne
@JoinColumn(name = "parent_id")
open var parent: Parent? = null
@Column(nullable = false)
open var data: String? = null
@Column(name = "version")
open var version: Int? = null
@PrePersist
@PreUpdate
private fun prepareVersion() {
if (parent != null) {
version = parent?.getChildPosition(this)
}
}
}
interface MyProjection {
// parent.id, child.id, child.version, child.data
}
@Repository
interface ParentRepository : JpaRepository<Parent, UUID> {
@Query("?")
fun findWithLatestChild(id: Long?): MyProjection?
}
是否可以使用 JPA 方法命名约定或 JPQL 查询来执行以下操作:
- 在 parent.id 上加入 parent 和 child。
- 在版本 (desc) 上订购 children 并将结果限制为 1。
- 投影 properties/columns 如上面的模拟投影界面中所述。
更新: 如果这不可行,以下本机查询描述了我的意图:
select p.id,c.* from parent p join child c on p.id = c.parent_id
where p.id = :parentId
order by c.version desc
limit 1
因此您可以创建这样的查询:
@Query("select new packagename.MyProjection(c.parent.id, c.id, c.version, c.data ) " +
"from Child where c.parent.id = :parentId order by c.version desc")
fun findWithLatestChild(id: Long?, pageable: Pageable): MyProjection?
然后用 PageRequest 调用它以将结果限制为 1
findWithLatestChild(PageRequest.of(0,1));