【问题标题】:Remove HasMany Association in HQL删除 HQL 中的 HasMany 关联
【发布时间】:2015-03-14 04:45:58
【问题描述】:

我的班级中有以下关联:

class A {
}

class B {

 static hasMany = [
    objects: A
  ]
}

我想使用 HQL 查询从所有 B 中删除关联。

这是我尝试过的:

B.executeUpdate("update B b set b.objects.id=NULL")

但前者不起作用。

如何删除 HasMany 关联 fin HQL?

【问题讨论】:

  • 所以澄清一下,因为您在A 中没有belongsTo,所以您有一个名称类似于b_a 的连接表,对吗?在从 B 实例的集合中清除所有 A 实例之后,您仍然希望所有 A 实例都在那里并且在没有拥有 B 的情况下分离?还是删除 A 实例?
  • @BurtBeckwith 是的,我没有belongsTo,是的,我有连接表。只需从 B 中删除 A 实例而不删除它们

标签: hibernate grails hql


【解决方案1】:

由于您想保留所有 A 和 B 实例,但只是分离它们,因此您这样做的最终效果是连接表将被清空。最有效的方法是使用 SQL:

delete from b_a

我找不到通过 HQL 执行此操作的任何方法,因为未映射连接表 - 它由 Hibernate 为您管理(就像在多对多中一样),但您没有任何直接访问它。通常,您将使用 Groovy/Java 代码中的实例,例如要删除一个B 实例的As,您可以这样做:

B b = ...
b.objects.clear()
b.save()

生成类似于

的SQL
delete from b_a where b.id=?

但是一次做一个显然效率低下,而且我在 Grails 或 Hibernate 方面都看不到任何批量选项。所以我只运行那个 SQL 查询,使用 SQL 最简单的方法是 groovy.sql.Sql:

import groovy.sql.Sql

class MyService {

   def dataSource

   void detachAllAsFromBs() {
       Sql sql = new Sql(dataSource)
       int rowCount = sql.executeUpdate('delete from b_a')
       log.debug "removed $rowCount entries from b_a"
   }
}

您可以忽略来自sql.executeUpdate 的返回值 - 删除的行数并不是特别有趣:

void detachAllAsFromBs() {
    new Sql(dataSource).executeUpdate 'delete from b_a'
}

【讨论】:

    【解决方案2】:

    您应该能够删除关联,而不是一直到 id。试试:

    B.executeUpdate("update B b set b.objects=NULL")
    

    由于这在 cmets 中不起作用(我认为这是正确的语法):您确定 B 和 A 之间的关系应该是静态的吗?那个地方的静态似乎是错误的,但如果没有堆栈跟踪或更多细节,就很难分辨。

    【讨论】:

    • 比“不起作用”更详细的信息吗?你有例外吗?什么版本的休眠。
    • 空集合没有意义(它们是空的或有元素) - 你如何想象你的 HQL 被转换为 SQL?
    • 当然是静态的,定义如下:grails.org/doc/latest/ref/Domain%20Classes/hasMany.html
    • 我的意思是逻辑上,在 OO/ORM 意义上。
    猜你喜欢
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多