每个子类的 Grails 继承 MongoDb 集合

Posted

技术标签:

【中文标题】每个子类的 Grails 继承 MongoDb 集合【英文标题】:Grails inheritance MongoDb collection per child class 【发布时间】:2014-08-16 01:24:47 【问题描述】:

在我使用 mongoDb 和继承的 Grails 2.3.8 应用程序中,我有这个基础域类:

class Record 
long batchID
static mapping =  tablePerHierarchy false 

还有这个子类:

class IndividualRecord extends Record 
    String uniqueId
    String firstName
    String middleName

    static mapping = 
        collection "individualRecords"
        database "twcdb"
    

    static constraints = 
        firstName(nullable: true)
        middleName(nullable: true)
    

问题是我希望我的子类映射到他们自己的 mongoDb 集合,但即使使用上面的配置,我的 IndividualRecord 对象也被保存在一个名为“record”的集合中,这是基类的名称。我错过了什么?有趣的是,无论我是否从子类中删除此代码,这种行为似乎都不会改变:

static mapping = 
        collection "individualRecords"
        database "twcdb"
    

【问题讨论】:

【参考方案1】:

MongoDB 插件目前不支持 tablePerHierarchy 设置继承,原因如下:

a) MongoDB 不支持连接,因此要获取所有数据,您需要执行多个查询,而这会导致性能不佳

b) 即使它确实支持tablePerHierarchy MongoDB 没有表,它也不会被称为。

【讨论】:

感谢您的回复。我只是认为,如果我的子记录在每个集合的基础上分开,这可能有助于搜索时间,这样我就可以拥有多个中型集合而不是一个大型集合。【参考方案2】:

使用聚合而不是继承:

class IndividualRecord 

 Record base

 static embedded = [ 'base' ]


【讨论】:

这会导致每个子类的单独集合吗? 是的,因为不会有父类或子类>)【参考方案3】:

使用 AbstractPersistanceListner 处理持久性事件。这是代码示例并在 bootstrap.groovy 中注册此侦听器。完整代码http://jagadeeshmanne.blogspot.in/2016/06/custom-persistence-listener-in-mongodb.html。您可以通过检查 entityObject.class.name.equals(IndividualRecord.class.name) 来分配属性值,然后分配 batchID 值

import org.grails.datastore.mapping.core.Datastore
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEvent
import org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener
import org.grails.datastore.mapping.engine.event.PreDeleteEvent
import org.springframework.context.ApplicationEvent

import org.grails.datastore.mapping.engine.event.EventType

class MongoPersistanceListener extends AbstractPersistenceEventListener  

    def springSecurityService

    public MongoPersistanceListener(final Datastore datastore, def springSecurityService) 
        super(datastore)
        this.springSecurityService = springSecurityService
    
    @Override
    protected void onPersistenceEvent(final AbstractPersistenceEvent event) 
        def entity = event.entityObject
        switch(event.eventType) 
            case EventType.PreInsert:
                initDefaults(entity)
                break
            case EventType.PostInsert:
                break
            case EventType.PreUpdate:
                def currentUser = springSecurityService.getCurrentUser()
                event.entityObject.updatedBy = currentUser ? currentUser.id : 0;
                event.entityObject.updatedOn = new Date();
                break;
            case EventType.PostUpdate:
                break;
            case PreDeleteEvent:
                break;
            case EventType.PostDelete:
                break;
            case EventType.PreLoad:
                break;
            case EventType.PostLoad:
                break;
            case EventType.Validation:
                initDefaults(entity)
                break;
        
    

    @Override
    public boolean supportsEventType(Class<!--? extends ApplicationEvent--> eventType) 
        return true
    

    void initDefaults(entity) 
        def currentUser = springSecurityService.getCurrentUser()
        if (entity.createdBy == null) 
            entity.createdBy = currentUser? currentUser.id : 0;
        
        if (entity.createdOn == null) 
            entity.createdOn = new Date();
        
        if (entity.updatedBy == null) 
            entity.updatedBy = currentUser? currentUser.id : 0;
        
        if (entity.updatedOn == null) 
            entity.updatedOn = new Date();
        
    

【讨论】:

以上是关于每个子类的 Grails 继承 MongoDb 集合的主要内容,如果未能解决你的问题,请参考以下文章

如何在 grails 域子类中添加对继承属性的约束

如何为 mongodb 副本集配置 grails 3

grails,mongodb - 多个数据库

6.18 (继承+(四类访问修饰符+程序集+静态方法))提纲

尝试使用 mongodb 插件在 grails 中创建 mongodb 集合

在 grails3 中使用 mongodb 和休眠