java - 使用 "pure"Hibernate/JPA 一次更新唯一列中的多个条目

标签 java hibernate jpa hql

我有一个存储任务的表,以及一个存储该任务的有序步骤的表。步骤属于任务父级(因此任务与步骤具有一对多关系),并且每个步骤都有一个“序数” - 它是哪个步骤号。我希望序号和父任务 ID 成为一个组合的唯一约束,因此例如单个任务不可能以设置为“步骤 1”的两个不同步骤结束,但不同的任务可以各自有自己的“步骤” 1”。

我希望能够同时更新属于任务的每个步骤的序号,这样我就不会违反唯一约束。因此,如果我有“步骤 1”、“步骤 2”和“步骤 3”,我可以在“步骤 2”处插入一个新步骤,并将现有步骤移动为“步骤 3”和“步骤 4”。我知道某些数据库允许您延迟检查约束,直到提交事务,但我非常希望能够避免任何需要特定数据库类型的事情,并完全在 JPA/Hibernate 中完成此操作。

这是我的实体的简化版本:

任务:

@Table
@Entity
public class Task {

    @Version
    private Long version;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private Set<Step> steps;
}

步骤:

@Entity
@Table(
    uniqueConstraints = {
        @UniqueConstraint(
            name = "UX_Step_Parent_Ordinal",
            columnNames = {"parent_id", "ordinal"})
    }
)
public class Step {

    @Version
    private Long version;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(nullable = false, name = "ordinal")
    private Long ordinal;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "parent_id")
    private Task parent;
}

到目前为止,我想出的唯一方法是首先在末尾插入新步骤,然后动态生成如下所示的 HQL 查询,该查询使用以下命令立即更新特定任务中的每个步骤案例:

UPDATE Step s
SET s.ordinal = CASE
 WHEN (s.id = 55) THEN 1
 WHEN (s.id = 58) THEN 2
 WHEN (s.id = 47) THEN 3
 WHEN (s.id = 33) THEN 4
 ... etc
 ELSE 0 END
WHERE s.parent.id = 5

但是我非常确定这需要引擎在每次发生查询时重新处理查询,因此无法利用查询缓存或其他加速等功能。是否有另一种方法可以使用 Hibernate/JPA 来做到这一点?

最佳答案

不确定它是否真的解决了问题,但我认为你应该将集合建模为 map :

@OneToMany
@MapKeyJoinColumn(Name="ordinal")
private Map<Long,Step> steps;

当您在中间的某个位置添加步骤时,您有责任更新整个 map 。

如果您仍然需要步骤中的序数,则必须将其设置为只读:

@Column(nullable = false, name = "ordinal", insertable=false, updateable=false)
private Long ordinal;

关于java - 使用 "pure"Hibernate/JPA 一次更新唯一列中的多个条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44928006/

相关文章:

java - Spring + Jboss7 @Transactional 不工作

java - JHipster多个数据源导致JdbcSQLSyntaxErrorException : Sequence "SEQUENCEGENERATOR" not found

hibernate - 帮助我了解 SEAM 和 Hibernate?

java - JPA错误: without eclipselink

java - 在 Android 中显示图像上的关键点 - OpenCV

java - 使用ADT的Postfix的双链接双栈Java

java - 从 Java 接口(interface)实现方法

java - 如何获取图像的路径?

jpa - 使用 JUnit 测试 EJB

java - Hibernate映射一个类到两个表(两个表多对一关系)