grailsgroovygrails-orm

Grails 5 - Is there a way to find out if a domain property has a formula in the mapping


I have a specifica scenario that require I know if one of my domain object properties has a formula in the static mapping.

It would be great if there were a method for this, but after hours of digging, I've been unable to find anything useful that isn't private.

Is there any way to get the static mapping to iterate over?

Or get whether a specific property is using a formula?


Solution

  • I figured out how to get the formula, though it's quite a bit more work than I feel it should be. Every property that I found that could have made this more terse was encapsulated.

    So I decided to add dynamic methods to the app's Domain classes with Groovy's runtime metaprogramming support.

    I've put this in doWithApplicationContext() of our Plugin.groovy file, but it should work in a Bootstrap.groovy if you aren't working on a plugin.

    def grailsApplication
    grailsApplication.domainClasses.each { domain ->
        /**
         * Find out if a Domain property is mapped with a formula.
         *
         * @param String property
         * @return Boolean
         *
         */
        domain.metaClass.static.isFormula = { String property ->
            def classPath = delegate.toString().replace("class", "").trim()
                return grailsApplication.getMappingContext()
                    .getPersistentEntity(classPath)
                    .propertiesByName[property]
                    .propertyMapping
                    .mappedForm
                    .formula
                    ?.size() > 0
        }
        /**
         * Get a Domain property's formula. Returns null if no formula is found.
         *
         * @param String property
         * @return String
         *
         */
        domain.metaClass.static.getFormula = { String property ->
            def classPath = delegate.toString().replace("class", "").trim()
                return grailsApplication.getMappingContext()
                    .getPersistentEntity(classPath)
                        .propertiesByName[property]
                        .propertyMapping
                        .mappedForm
                        .formula ?: null
        }
    }
    

    And to use them, you call them statically off your domain class.

    import your.app.Payment
    
    if (Payment.isFormula("transactionType")) {
        String formula = Payment.getFormula("transactionType")
    }