【问题标题】:Liquibase: onDelete="CASCADE" - deleting parent doesn't delete child, but deleting child deletes parentLiquibase:onDelete="CASCADE" - 删除父级不会删除子级,但删除子级会删除父级
【发布时间】:2021-12-02 20:20:06
【问题描述】:

我有两个实体(给你简化版本):

<createTable tableName="wallet_information"
             remarks="A table to contain wallet data">
    <column name="id" type="bigint(20)" autoIncrement="true">
        <constraints nullable="false" primaryKey="true"/>
    </column>
    <column name="user_uuid" type="varchar(255)">
        <constraints nullable="false"/>
    </column>
    <column name="wallet_name" type="varchar(255)">
        <constraints nullable="false"/>
    </column>
    <column name="wallet_address" type="varchar(63)">
        <constraints nullable="false"/>
    </column>
    <column name="verification_challenge_id" type="bigint(20)">
        <constraints nullable="true"/>
    </column>
</createTable>

还有:

<createTable tableName="verification_challenge"
             remarks="A table to contain challenge data">
    <column name="id" type="bigint(20)" autoIncrement="true">
        <constraints nullable="false" primaryKey="true"/>
    </column>
    <column name="challenge_type" type="varchar(255)">
        <constraints nullable="false"/>
    </column>
</createTable>

最后:

   <addForeignKeyConstraint baseTableName="wallet_information" 
        baseColumnNames="verification_challenge_id"
        constraintName="verification_challenge_fk"
        referencedTableName="verification_challenge" 
        referencedColumnNames="id"
        onDelete="CASCADE"/>

然后我使用 Hibernate 在这些表中保存一些数据。

目前我没有从代码的角度从这些表中删除任何数据,但是当我手动删除 wallet_information 中的条目时,verification_challenge 中引用的条目并不会随之删除。

但是当我删除verification_challenge 中的条目时,wallet_information 中引用的条目被删除。

我认为onDelete="CASCADE" 的行为会完全相反...

我做错了什么?

【问题讨论】:

    标签: java mysql hibernate foreign-keys liquibase


    【解决方案1】:

    我认为您的外键设置与业务逻辑的预期相反。

    在 Liquibase 方面,它只是生成像alter table wallet_information add constraint verification_challenge_fk ... on delete cascade 这样的 SQL,它告诉数据库“当你有一个删除会导致这个约束失败时,删除有问题的数据”。因此,在您的情况下,“当您删除验证挑战时,请删除钱包信息”。

    因此,您的解决方法应该是从wallet_information 中删除verification_challenge_id 列,并将wallet_information_id 列添加到verification_challenge。然后,onDelete=cascade 逻辑将符合您的预期。

    【讨论】:

    • 一个愚蠢的问题,但是我应该如何从 java 代码的角度从wallet_information 访问verification_challenge?据我了解-我应该从WalletInformation 对象中删除@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn(name = "verification_challenge_id") private VerificationChallenge verificationChallenge;,并将WalletInformation 添加到VerificationChallenge。因此,当从数据库中选择WalletInformation 时,我不会附加VerificationChallenge。我应该使用另一个数据库请求吗?
    • 我已经有一段时间没有使用hibernate了,所以我不知道。不过,如果我没记错的话,您可以将映射设置为双向,因此可以从任一侧引用两个对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    • 2014-05-28
    • 1970-01-01
    • 2020-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多