sql - 访问 hql 查询中的连接表以获取 grails 中的多对多关系

标签 sql hibernate grails hql grails-orm

我在 grails 中有 2 个具有多对多关系的域类:套牌和卡片。

设置如下所示:

class Deck {
static hasMany = [cards: Card]
}

class Card {
static hasMany = [decks: Deck]
static belongsTo = Deck
}

删除牌组后,我还想删除不再属于牌组的所有牌。完成此操作的最简单方法是编写类似于以下 sql 的内容:
delete from card where card.id not in(select card_id from deck_cards);

但是,我不知道如何编写将解析为该 SQL 的 HQL 查询,因为连接表 deck_cards 没有相应的 grails 域类。我无法使用普通连接编写此语句,因为 HQL 不允许您在删除语句中使用连接,并且如果我使用子查询来绕过此限制,mySQL 会提示,因为不允许您引用您所在的表从子查询的“从”部分中删除。

我还尝试使用 hibernate “删除-孤儿”级联选项,但这会导致在删除牌组时删除所有牌,即使这些牌也属于其他牌组。我快疯了——这似乎应该是一个简单的任务。

编辑
对于“套牌”和“卡片”的这种特定用途似乎有些混淆。在这个应用程序中,“卡片”是抽认卡,一副卡片中可能有数万张。此外,有时需要制作套牌的副本,以便用户可以根据需要对其进行编辑。在这种情况下,新牌组不会复制所有牌,而是只引用与旧牌组相同的牌,如果只有一张牌被更改,就会创建一张新牌。此外,虽然我可以在 groovy 的循环中执行此删除操作,但它会非常缓慢且占用大量资源,因为它会生成数万条 sql 删除语句,而不仅仅是 1 条(使用上面的 sql)。有没有办法访问 HQL 中连接表的属性?

最佳答案

首先,我在您的实体中看不到重点。
让一张牌属于多个套牌是不合逻辑的。两者兼有是不合逻辑的belongTohasMany .

无论如何,不​​要使用 HQL 进行删除。

如果您确实需要 OneToMany , 使用 session.remove(deck)并设置 cascadecardsREMOVEALL .

如果你真的想要ManyToMany ,对实体进行手动检查。在伪代码中(因为我不知道 grails):

for (Card card : deck.cards} {
    if (card.decks.size == 0) {
        session.remove(card);
    }
}

关于sql - 访问 hql 查询中的连接表以获取 grails 中的多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2019073/

相关文章:

SQL Always 加密 CMK 证书存储最佳实践

java - JPA Hibernate Postgres 错误 - 运算符不存在 : boolean = integer

mysql - JPA 一元运算符

mysql - 在同一个表上具有多个连接的 Hibernate native 查询返回错误结果

grails - 对Grails应用程序进行国际化时出错

sql - 使用 dbt 从雪花 information_schema 检索表名称

python - sql 喜欢交替

mysql - sql查询\作为要检查的值

hibernate - 服务器重新启动后,将继续创建已删除的字段

grails - GSP-选择标签。如何实现选定的=“selected”