Multiple many-to-many associations in one Grails domain class

做~自己de王妃 提交于 2020-01-05 01:10:10

问题


I am using Grails 3.0.6 and am struggling with a complicated and highly interconnected domain model. I have classes with multiple many-to-many associations to other classes and I am left with no choice but to have multiple belongsTo associations on at least one class. I am unable to figure out the syntax to represent this.

My domain model was quite complicated, but I was able to reduce my problem to this simplified example:

class Graph {
    static hasMany = [vertices: Vertex]
}

class OtherClass {
    static hasMany = [vertices: Vertex]
}

class Vertex {
    static hasMany = [graph: Graph, other: OtherClass]
}

In this simplified example, I could get around the problem by declaring the ownership between the domain classes on Graph and OtherClass... In my complicated domain model, I don't have this choice because there are too many classes with multiple many-to-many associations.

I have tried this:

class Vertex {
    static hasMany = [graphs: Graph, others: OtherClass]
    static belongsTo = Graph, OtherClass
}

but I get an NPE.

I have tried this:

class Vertex {
    static hasMany = [graphs: Graph, others: OtherClass]
    static belongsTo = [graphs: Graph, others: OtherClass]
}

but I still get "GrailsDomainException: No owner defined between domain classes [Graph] and [Vertex]"

Is there something I could do with mappedBy to correctly represent this?

In many of my many-to-many associations, cascading saves are not actually wanted (although they won't hurt), so I don't need belongsTo (or an "owner") for that purpose. This makes me wonder if associations on the domain classes are really how I should be modeling these relationships. Is there something else I could be doing?


回答1:


per Burt Beckwith's comment, I created an additional domain class to represent the join table. Now, one many-to-many association is broken down into two one-to-many associations and the problem does not arise.

Example:

class Graph {
    static hasMany = [graphVertexRelations: GraphVertexRelation]
}

class OtherClass {
    static hasMany = [vertices: Vertex]
}

class Vertex {
    static hasMany = [graphVertexRelations: GraphVertexRelation, others: OtherClass]
    static belongsTo = OtherClass
}

class GraphVertexRelation {
    static belongsTo = [graph: Graph, vertex: Vertex]

    static GraphVertexRelation create(Graph graph, Vertex vertex, boolean flush = false) {
        new GraphVertexRelation(graph: graph, vertex: vertex).save(flush: flush, insert: true)
    }
}



回答2:


The exception that you're seeing "GrailsDomainException: No owner defined between domain classes [Graph] and [Vertex]" means that the ORM can't figure out what the base class is, and there is a cyclical relationship between Graph and Vertex.

If you want to maintain the relationship to see what Graph a Vertex is in, you can do a backwards lookup using a criteria.

class Graph {
    static hasMany = [vertices: Vertex]
}

class OtherClass {
    static hasMany = [vertices: Vertex]
}

class Vertex {
    static transients = ['graphs']
    static hasMany = [other: OtherClass]

    List<Graph> getGraphs() {
        // Backwards link, using the graph table
        Graph.withCriteria() {
            vertices {
                inList("id", [this.id.toLong()])
            }
        }
    }
}


来源:https://stackoverflow.com/questions/32873388/multiple-many-to-many-associations-in-one-grails-domain-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!