当前位置: 首页 > 知识库问答 >
问题:

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

石臻
2023-03-14

我试图建模双向亲子设计,有秩序的孩子。

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

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

  • 从架构中删除唯一约束
  • 自己显式管理排序,而不是依赖hibernate

有什么方法可以让Hibernate生成sql,在更新之前删除吗?

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

DELETE然后在集合中插入-执行的顺序SQL

DB架构:

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>();
}

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>

共有1个答案

公西马鲁
2023-03-14

Hibernate不会直接执行HQL(或SQL)语句,但是在执行提交()flush()时,它会重新排序SQL语句,目标是在最有效的方法。但这种情况也可能发生Hibernate的重新排序是错误的,例如会导致违反约束,就像您的情况一样。

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

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

transaction = session.beginTransaction();
session.delete(obj);
session.flush();     /* newly introduced */
session.update(...);
transaction.commit();

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

 类似资料:
  • 我正在尝试使用JavaDOM解析器为XML文档中的许多标记建立索引,以从中形成类似MIB的结构(例如 我希望将模块映射到1,将容器映射到1.1,将列表映射到1.1.1,将叶映射到1.1.1.1,将另一个叶映射到1.1.1.2(我已经有了这样做的方法),但在嵌套相同命名的XML标记时,我遇到了问题。以下是我创建的函数——为了简单起见,只需打印属性名 下面是我试图解析的XML示例: 当我在这个程序上运

  • 问题内容: 我有一个带有数据库转储的SQL脚本。如何使用Hibernate执行它? 我这样尝试过: 但是它仅在包含单个SQL查询且我需要运行多个插入和其他复杂内容时才有效。 RDBMS:Oracle数据库11g快捷版11.2.0.2.0版-64位生产 问题答案: 用开始结束块包装查询。喜欢

  • 我不确定如何获得SQL执行所影响的行数。 我确实喜欢这样: 返回: (1)SQL数据操作语言(DML)语句的行计数,或(2)0表示不返回任何内容的SQL语句 啊! 我希望是: 从中提取第一个单词。字以空格或EOL行字符结束。 如果该单词(忽略大小写)是INSERT、UPDATE或DELETE,那么它是一个DML语句,并且的输出是相关的,否则的输出是无关的。 丑陋和容易出错。但这个问题唯一可能的解决

  • 问题内容: 这个问题与执行顺序无关。这只是关于ORDER BY。 在标准执行中是: FROM WHERE GROUP BY HAVING SELECT ORDER BY TOP 编辑:这个问题或多或少是“ 执行ORDER BY表达式时SQL Server是否应用短路评估吗? ”的答案是有时!我只是还没有找到一个合理的理由。参见编辑#4。 现在假设我有一个这样的声明: 这不是我要执行的真实语句,而只

  • 问题内容: 我有类似的代码 它没有在node.js中按顺序执行,因此在执行结束时得到一个空数组。问题是它将先执行然后执行 我的代码中是否有任何错误或执行此操作的任何其他方式?谢谢! 问题答案: 您可能已经知道,事情在node.js中异步运行。因此,当您需要使事物按特定顺序运行时,您需要利用控件库或基本上自己实现。 我强烈建议您看一下async,因为它可以轻松地使您执行以下操作: 在这里看到的主要内

  • 我试图理解hibernate是如何工作的,即在类上放置@Entity是如何使它成为一个持久类的?即