Java 如何在hibernate中更改sql执行顺序

Java 如何在hibernate中更改sql执行顺序,java,sql,hibernate,unique-constraint,self-referencing-table,Java,Sql,Hibernate,Unique Constraint,Self Referencing Table,我试图用有序的子对象来模拟双向父子设计 从父级中删除子级(例如,子级#2/3子级)时,hibernate生成的sql会导致唯一的约束冲突,因为“更新”(同级)是在“删除”(目标)之前执行的 我使用的RDBMS(H2)不支持延迟约束。除了以下选项外,我还有哪些选择 从模式中删除唯一约束 自己显式管理排序,而不是依赖hibernate 有没有办法让hibernate在“更新”之前生成带有“删除”的sql 论坛上有一些古老的讨论: 数据库模式: CREATE TABLE IF NOT EXI

我试图用有序的子对象来模拟双向父子设计

从父级中删除子级(例如,子级#2/3子级)时,hibernate生成的sql会导致唯一的约束冲突,因为“更新”(同级)是在“删除”(目标)之前执行的

我使用的RDBMS(H2)不支持延迟约束。除了以下选项外,我还有哪些选择

  • 从模式中删除唯一约束
  • 自己显式管理排序,而不是依赖hibernate
有没有办法让hibernate在“更新”之前生成带有“删除”的sql


论坛上有一些古老的讨论:


数据库模式:

CREATE TABLE IF NOT EXISTS  Sequences (
ID                      BIGINT NOT NULL AUTO_INCREMENT,
Name                    LONGVARCHAR,
Type                    LONGVARCHAR,
Sequence                LONGVARCHAR,

ParentId                BIGINT DEFAULT NULL,
Index                   INT,

CONSTRAINT pk_SequenceId    PRIMARY KEY     (ID),
CONSTRAINT uc_Sequences     UNIQUE          (ParentId, Index),
CONSTRAINT fk_Sequences
    FOREIGN KEY (ParentId) 
    REFERENCES Sequences(ID) 
        ON UPDATE CASCADE
        ON DELETE CASCADE
);
类别:

public class Sequence {
    protected Long ID;
    protected String name;
    protected String type;
    protected String sequence;
    protected Sequence  parentSequence;
    protected List<Sequence> childSequences = new ArrayList<Sequence>();
}
公共类序列{
保护长ID;
受保护的字符串名称;
保护字符串类型;
受保护字符串序列;
保护序列父序列;
受保护列表子序列=新ArrayList();
}
HBM映射:

<hibernate-mapping>
<class name="Sequence" table="Sequences">
    <id name="ID" column="ID" type="long">
        <generator class="native"/>
    </id>

    <property name="name" type="string" column="Name"/>
    <property name="type" type="string" column="Type"/>
    <property name="sequence" type="string" column="Sequence"/>

    <many-to-one name="parentSequence" column="parentId" cascade="save-update" insert="false" update="false" class="Sequence" />

    <list name="childSequences" inverse="false" lazy="true" cascade="all-delete-orphan">
        <key column="parentId" not-null="true"/>
        <list-index column="Index" base="0"/>
        <one-to-many class="Sequence"/>
    </list>
</class>


Hibernate不直接执行HQL(或SQL)语句,而是在执行
commit()
flush()
时重新排序SQL语句,目标是以最有效的方式执行它们。但是,如果从Hibernate重新排序是错误的,例如会导致违反约束,就像您的情况一样

解决方案是引入一个中间的
flush()
flush()
强制重新排序并发送SQL语句,但不会提交

在您的情况下,您可以修改代码,如(作为草图):


如果问题出现在级联删除或Hibernate在没有您控制的情况下执行的某些删除中,那么您必须控制删除和更新过程,并在代码中明确地执行操作,而不是依赖Hibernate的自动操作。

谢谢您的建议。手动执行重新排序将非常困难,因为在对象返回到持久化模块之前(例如,保存时),可能会发生多个操作(交错添加/删除)(应用程序业务逻辑运行):(顺便说一句,刷新也可能是隐式的;当您调用特定的选择查询时,仍有待刷新的更改,Hibernate可能会决定自己刷新这些更改。
transaction = session.beginTransaction();
session.delete(obj);
session.flush();     /* newly introduced */
session.update(...);
transaction.commit();