Search code examples
exceptiongrailsassociationsgrails-orm

Grails GORM association unmapped exception


I'm creating a Grails 2.4.3 app and have the following Domain classes:

class StockItem {
    String name
    BigDecimal wholesalePrice
    BigDecimal retailPrice
    BigDecimal profit

    static belongsTo = [ledger: Ledger]

    static constraints = {
        name minSize:3, maxSize:255
        wholesalePrice min:0.0, scale:2
        retailPrice min:0.0, scale:2
        retailPrice validator: { retailPrice, StockItem obj ->
            if (retailPrice < obj.wholesalePrice) {
                ['retailLessThanWholesale']
            }
        }
    }

    static mapping = { 
        profit(formula: 'RETAIL_PRICE - WHOLESALE_PRICE') 
    }
}

class Ledger {
    String name

    static hasMany = [clients: Client, invoices: Invoice, availableItems: StockItem, payments: Payment]

    static constraints = {
        name unique:true
    }
}

I have a unit test:

@Domain(StockItem)
@TestMixin(HibernateTestMixin)
class StockItemSpec extends Specification {
    void "Test profit calculation"() {
        when: "a stock item exists"
        StockItem i = new StockItem(name: "pencil", wholesalePrice: 1.50, retailPrice: 2.75)

        then: "profit is calculated correctly"
        i.profit == 1.25
    }

}

that is failing thusly:

Failure:  Test profit calculation(com.waldoware.invoicer.StockItemSpec)
|  org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is 
org.hibernate.MappingException: An association from the table stock_item refers to an unmapped class: com.waldoware.invoicer.Ledger

The app seems to be functioning OK, and I can't understand why this test is failing. Any ideas are appreciated!


Solution

  • Since a belongsTo association exists between your StockItem and Ledger domain classes, you will need to add Ledger to the @Domain annotation in your test:

    @Domain([StockItem, Ledger])
    

    This should properly configure the required domain classes when the unit test runtime is initialized. Depending on your other test cases, you may also need to include Client or Payment in the annotation.