Grails: Prevent cascading association between two domain classes with multiple relationships

前端 未结 3 545
攒了一身酷
攒了一身酷 2021-01-28 13:12

Consider two domain classes; Job and Quote.

A Job has many Quotes but a Job also has an accepted quote. The accepted quote is nullable and should only be set once a part

相关标签:
3条回答
  • 2021-01-28 13:50

    This may not be what you are looking for but I would actually model this a little differently - I would have an accepted flag in the Quote domain:

    class Job {
        String title
        static hasMany = [quotes: Quote]
    }
    
    class Quote {
        static belongsTo = [job: Job]
        BigDecimal quoteAmount
        Boolean accepted
    }
    

    Then your persistence could look like this:

    jobInstance.addToQuotes(new Quote(quoteAmount: 123.34, accepted: false)) //or true
    

    and no worries regarding your original problem.

    You could also add a transient and its getter to the Job class to get the accepted Quote

    class Job {
        String title
        static hasMany = [quotes: Quote]
    
        static transients = ['acceptedQuote']
    
        Quote getAcceptedQuote() {
            return Quote.findByJobAndAccepted(this, true)
        }
    
    }
    
    0 讨论(0)
  • 2021-01-28 13:50

    Grails/GORM has made the associations simpler by following the methodology of convention over configuration and making things more verbose.

    What do you think of the below structure of the domain classes?

    class Job {
        String title
        static hasMany = [quotes: Quote]//Job has many Quotes. Note: Accepted Quote is one of them.
    }
    
    class Quote {
        BigDecimal quoteAmount
        Boolean isAccepted
    
        static belongsTo = [job: Job]//Quote always belongs to a Job.
        //When a Job is deleted, quote is also cascade deleted.
    }
    

    Now if you create your quote like below then everything should work perfectly:

    def job = new Job(title: "Test Job").save()
    //Just adding a quote
    def quoteInstance = new Quote(quoteAmount: amount)
    job.addToQuotes(quoteInstance)
    job.save()
    
    //Now accepting that quote
    quoteInstance.isAccepted = true
    job.save()
    

    Done.

    Do we need an acceptedQuote reference in Job? No
    How to get to the acceptedQuote?

    def acceptedQuote = job.quotes.find{it.isAccepted}

    0 讨论(0)
  • 2021-01-28 13:53

    Take a look at hasOne and belongsTo association configuration. Take a look at cascade to learn more about cascade behaviour configuration.

    0 讨论(0)
提交回复
热议问题