0

Using Grails with the following versions:

APPLICATION STATUS
App version: 0.1
Grails version: 2.3.5
Groovy version: 2.1.9
JVM version: 1.7.0_51
Reloading active: true
Controllers: 15
Domains: 18
Services: 2
Tag Libraries: 13

I have a domain model that I am trying to follow. I built the tables in MySQL prior to programming.
In the model, I have Insertion_orders that are bound to people (Persons) in a Many-to-Many relationship. This relationship is defined by Insertion_orders_persons, with the person_id & location_id defining an entry in Insertion_orders_persons. In addition there is a type value that is ENUMed either Trafficker, Advertiser, Agency, (or) Salesperson. One (or more) trafficker will always appear, but the rest may, may not or have many of these associations. I am trying to bind them according to type to the Insertion_orders model:

package cms


class Insertion_orders {
    String insertion_order_name
    String po_number
    String notes
    String toString() {
        "${insertion_order_name} - ${id}"
    }

    static hasMany = [trafficker: Insertion_orders_traffickers, salesperson: Insertion_orders_salespersons]

    static constraints = {
        insertion_order_name(blank:false)
        po_number()
        notes(widget: 'textarea', nullable:true)
    }
    static mapping ={
        version false
        id column: 'insertion_order_id'
        notes sqlType: 'text'
    }
}

I am trying to use inheritance and a discrimiator value to accomplish this.

package cms

class Insertion_orders_persons {
    Persons person
    Insertion_orders insertion_order
    Type type
    String toString() {
        "${person}: ${type}"
    }

    enum Type {
        Trafficker, Salesperson, Advertiser, Agency
    }

    static constraints = {
    }
    static mapping = {
        version false
        id column: 'insertion_order_person_id'
        discriminator column: "type"        
    }

}

class Insertion_orders_traffickers extends Insertion_orders_persons {
    static mapping ={
        discriminator value: "Traffickers"
    }
}

class Insertion_orders_salespersons extends Insertion_orders_persons {
    static mapping ={
        discriminator value: "Salesperson"
    }
}

The problem is that when I try to join to the extended classes (as in the hasMany in the Insertion_orders class), the Grails fails to start and generates the following:

|Loading Grails 2.3.5
|Configuring classpath
.
|Environment set to development
.................................
|Packaging Grails application
..........................................
|Running Grails application
Error |
2014-04-16 11:33:58,693 [localhost-startStop-1] ERROR context.GrailsContextLoader  - Error initializing the application: Error creating bean with name 'transactionManagerPostProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.hibernate.MappingException: Association references unmapped class: cms.Insertion_orders_salespersons
Message: Error creating bean with name 'transactionManagerPostProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.hibernate.MappingException: Association references unmapped class: cms.Insertion_orders_salespersons
    Line | Method
->>  262 | run       in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    744 | run       in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.hibernate.MappingException: Association references unmapped class: cms.Insertion_orders_salespersons
->>  262 | run       in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    744 | run       in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.hibernate.MappingException: Association references unmapped class: cms.Insertion_orders_salespersons
->>  262 | run       in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    744 | run       in java.lang.Thread
Caused by MappingException: Association references unmapped class: cms.Insertion_orders_salespersons
->>  262 | run       in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    744 | run       in java.lang.Thread
Error |
Forked Grails VM exited with error

As additional information, regardless of how I try to access the subclasses, or the subclass composition, I get the same error.

This seems like a very fundamental functionality. Can someone please tell me what I am missing or doing incorrectly?

Marque
  • 1
  • 2
  • I don't think it will fix the problem but why are you using snake case format for your domain classes instead of camel case? – Fran García Apr 16 '14 at 16:16
  • << I have a domain model that I am trying to follow. I built the tables in MySQL prior to programming. >> I suspect this is something to do with your data source and database mapping? – Develop4Life Apr 16 '14 at 16:19
  • That is a good thought danielad. I created a whole new Grails Project, using the default DataSource (i.e. h2 in memory), rebuilt all 3 domain classes and added a few controllers with dynamic scaffolding. Generated the same error message. – Marque Apr 16 '14 at 16:47

1 Answers1

0

If you remove discriminator column: “type” from Insertion_orders_persons and define Insertion_orders_persons, Insertion_orders_traffickers and Insertion_orders_salespersons each in their own source files, I think you code will work.

Jeff Scott Brown
  • 26,804
  • 2
  • 30
  • 47
  • It does for me. If you can post an example project to github which demonstrates what you are seeing, I will be happy to look at it. – Jeff Scott Brown Apr 16 '14 at 17:25
  • See the commit history at [github.com/jeffbrown/subclassquestion/commits/master](https://github.com/jeffbrown/subclassquestion/commits/master). That code appears to work. – Jeff Scott Brown Apr 16 '14 at 17:34
  • I apologize, you are correct. Is there anyway to use some value "other" than the class column? By leaving in Type i get an error ending with "Caused by MappingException: Repeated column in mapping for entity: cms.Insertion_orders_traffickers column: type (should be mapped with insert="false" update="false") | 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor | 615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker ^ 744 | run in java.lang.Thread Error | Forked Grails VM exited with error – Marque Apr 16 '14 at 18:00
  • > Is there anyway to use some value "other" than the class column? I don't know what you mean by that. What are you trying to accomplish? – Jeff Scott Brown Apr 16 '14 at 18:05
  • I can't tell what you are asking but I think the original issue described here is addressed by my earlier suggestion. See http://grails.org/doc/latest/ref/Database%20Mapping/discriminator.html. Does that help? If not let me know what it is you are trying to accomplish. – Jeff Scott Brown Apr 16 '14 at 18:53
  • Thanks. I figured it out. The discirminator column was also defined as an enum type both at the DB level and within the Domain class. Once that was converted to just a String (varchar), it worked with the cloumn name I gave it. I have a number of join tables with an attribute that defines the nature of the association. I generally like limiting those in an explicitly and centrally defined manner (whether it is enums or a one-to-many table). The information and help you provided "unstuck" me. Thanks. – Marque Apr 17 '14 at 13:20