Search code examples
mysqlgrailsgrails-ormabstractextends

Grails, MySQL and extended classes


Here is my abstract class :

package mypackage.commons

abstract class Content {
    String name

    static constraints = {
        name nullable: false, blank: false, size: 1..50
    }
}

Here is my class which is extended :

package mypackage.project

import mypackage.commons.Content

class Plane extends Content {
    String something;
}

Here is my Bootstrap.groovy file :

package mypackage

import mypackage.commons.Content
import mypackage.project.Plane

class BootStrap {

    def init = { servletContext ->

        Plane boing1 = new Plane (name: 'Boing', something: 'Hello').save()
        Plane boing2 = new Plane (name: 'Boing', something: 'Goodbye').save()
        
    }
    def destroy = {
    }
}

The problem is when I go on MySQL, when I use SHOW TABLES, I only can see content plane.

Here is the content of SELECT * FROM content;

+----+---------+-------+-------------------------+-----------+
| id | version | name  | class                   | something |
+----+---------+-------+-------------------------+-----------+
|  1 |       0 | Boing | mypackage.project.Plane | Hello     |
|  2 |       0 | Boing | mypackage.project.Plane | Goodbye   |
+----+---------+-------+-------------------------+-----------+

EDIT

After testing Mike's answer :

package mypackage.commons

abstract class Content {
    String name

    static constraints = {
        name nullable: false, blank: false, size: 1..50
    }

    static mapping = {
        tablePerHierarchy false
    }
}

here is the result of SHOW TABLES

+-----------------------+
| Tables_in_my_database |
+-----------------------+
|  content              |
|  plane                |
+-----------------------+

Here is the result of SELECT * FROM content :

+----+---------+-------+
| id | version | name  |
+----+---------+-------+
|  1 |       0 | Boing |
|  2 |       0 | Boing |
+----+---------+-------+

Here is the result of SELECT * FROM plane :

+----+------------+
| id |  something |
+----+------------+
|  1 |  Hello     |
|  2 |  Goodbye   |
+----+------------+

END OF EDIT

Expected behaviour :

SHOW TABLES; should show me only the table plane

SELECT * FROM plane should show me this :

+----+---------+-------+------------+
| id | version | name  |  something |
+----+---------+-------+------------+
|  1 |       0 | Boing |  Hello     |
|  2 |       0 | Boing |  Goodbye   |
+----+---------+-------+------------+

How can I obtain the expected result ?

Is it possible ?

Thanks in advance.


Solution

  • I found an answer, I wonder if it's the best way, but it works.

    This topic helps me : https://github.com/grails/grails-data-mapping/issues/1254

    Firstly, I understand that if I don't want a class to be mapped by Grails, I have to put this class outside of "Domain" package.

    So I moove my Content class into src -> main -> groovy -> common (I created this folder) -> Content.groovy

    Here is my Content class :

    package common
    
    abstract class Content {
        String name
    
        static constraints = {
            name nullable: false, blank: false, size: 1..50
        }
    }
    

    Here is my Plane class :

    package mypackage.project
    
    import common.Content
    
    class Plane extends Content {
        String something;
    }
    

    And here is my Bootstrap.groovy :

    package mypackage
    
    import mypackage.project.Plane
    
    class BootStrap {
    
        def init = { servletContext ->
    
            Plane boing1 = new Plane (name: 'Boing', something: 'Hello').save()
            Plane boing2 = new Plane (name: 'Boing', something: 'Goodbye').save()
            
        }
        def destroy = {
        }
    }
    

    So I avoid tablePerHierarchy use.

    In the topic, thay talked about @MappedSupperclass, I don't know what it refers to. I did not use it.

    Expected behaviour is reach.

    Is it the correct way to do it ?