GORM 阻止为域创建外键约束 [英] GORM prevent creation of a foreign key constraint for a Domain

查看:55
本文介绍了GORM 阻止为域创建外键约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 Grails 中开发一个基于 Web 的应用程序.我遇到了一种情况,我想尝试禁止 GORM 在表中的字段上创建外键约束.

I am developing a web based application in Grails. I have come across a situation where I would like to try and suppress GORM from creating a foreign key constraint on a field in a table.

我有一个域类,它是类层次结构的一部分.域类本质上充当到目标域的链接.目标域可以是不同的类型,并且该链接域的每个子类都旨在为每个特定类型的链接项目提供链接.这些链接项具有某些共同行为,即实现相同的接口,但在其他方面有所不同,以至于它们存储在不同的表中.

I have a domain class which is part of a class hierarchy. The domain class essentially acts as a link to a target domain. The target domain can be of different types and each of the subclasses of this link domain is designed to provide the link for each specific type of linked item. These linked items have certain behaviour in common i.e. implement the same interface but otherwise are different to the point that they are stored in different tables.

在此链接域表中,有一列表示被链接到的项目的 ID.所有链接的项目都具有相同的基于整数的 id.问题是 GORM 试图为同一个表列创建多个外键约束,每个链接域子类一个外键约束,代表不同类型的链接项.我知道我可以为每次其他 id 列为空的 id 设置单独的列,但这似乎有点混乱.如果有办法告诉 GORM 我不希望它在该列上创建外键约束(因为不同的外键使用同一列)可以解决问题.

Within this link domain table there is one column which represents the id of the item being linked to. All the linked items have the same integer based id. The problem is that GORM tries to create multiple foreign key constraints of this same table column, one for each of the link domain subclasses which represents a different type of linked item. I know I could have separate columns for the id of each time where the other id columns would be null but this seems kind of messy. If there were a way to just tell GORM I don't want it to create a foreign key constraint on that column (because different foreign keys use the same column) that would solve the problem.

我知道问题来自于参照完整性以及是否可以将链接键值放入外部表中不存在的列中,但应用程序应防止这种情况发生.

I know that the question comes up of referential integrity and whether a link key value could be put in the column which does not exist in the foreign table but the application should prevent this situation from occurring.

如果不这样做,我将不得不手动加载链接的项目,而不是依赖 GORM 自动完成.

failing this then I would have to deal with loading the linked item manually and not rely on GORM to do it automatically.

推荐答案

经过相对较短的谷歌搜索,我找到了 Burt Beckwith 的博客条目:http://burtbeckwith.com/blog/?p=465 解释了 GORM 自定义的基础知识.通过以下配置类,我设法防止创建我不想创建的密钥.在 Burt 的示例中,需要一个 RootClass,但这不符合我的需要,因此省略了检查.

After a relatively short googling I found Burt Beckwith's blog entry: http://burtbeckwith.com/blog/?p=465 that explains the basics of GORM customization. With the following configuration class I managed to prevent creation of a key I did not want to get created. In Burt's example a RootClass is required, but this did not suit my needs so the checking is omitted.

package com.myapp;

import com.myapp.objects.SomeClass;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration;
import org.hibernate.MappingException;
import org.hibernate.mapping.ForeignKey;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;

import java.util.Collection;
import java.util.Iterator;

public class DomainConfiguration extends GrailsAnnotationConfiguration {
    private static final long serialVersionUID = 1;

    private boolean _alreadyProcessed;

    @SuppressWarnings({"unchecked", "rawtypes"})
    @Override
    protected void secondPassCompile() throws MappingException {
        super.secondPassCompile();

        if(_alreadyProcessed) {
            return;
        }

        Log log = LogFactory.getLog(DomainConfiguration.class.getName());

        for(PersistentClass pc : (Collection<PersistentClass>) classes.values()) {
            boolean preventFkCreation = false;
            String fkReferencedEntityNameToPrevent = null;

            if("com.myapp.objects.SomeClassWithUnwantedFkThatHasSomeClassAsAMember".equals(pc.getClassName())) {
                preventFkCreation = true;
                fkReferencedEntityNameToPrevent = SomeClass.class.getName();
            }

            if(preventFkCreation) {
                for(Iterator iter = pc.getTable().getForeignKeyIterator(); iter.hasNext(); ) {
                    ForeignKey fk = (ForeignKey) iter.next();

                    if(fk.getReferencedEntityName().equals(fkReferencedEntityNameToPrevent)) {
                        iter.remove();
                        log.info("Prevented creation of foreign key referencing " + fkReferencedEntityNameToPrevent + " in " + pc.getClassName() + ".");
                    }
                }
            }
        }

        _alreadyProcessed = true;
    }
}

通过将配置类放到datasource.groovy中,将其引入Grails:

The configuration class is introduced to Grails by putting it to datasource.groovy:

dataSource {
    ...
    ...
    configClass = 'com.myapp.DomainConfiguration
}

这篇关于GORM 阻止为域创建外键约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆