Spring Roo
  1. Spring Roo
  2. ROO-292

Support @MappedSuperclass and @Inheritance when creating entities

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.0.0.RC2
    • Fix Version/s: 1.0.0.RC3
    • Component/s: PERSISTENCE
    • Labels:
      None

      Description

      It is possible to create a class hierarchy by executing the following commands:

      entity --name ~.model.AbstractEntity --abstract
      entity --name ~.model.MyEntity1 --extends ~.model.AbstractEntity
      entity --name ~.model.MyEntity2 --extends ~.model.AbstractEntity
      

      All classes are annotated by @Entity and this implies @Inheritance(strategy=InheritanceType.SINGLE_TABLE).
      In many cases this is not suitable.

      So it would be nice to have a parameter '--inheritanceStrategy' (in case '--abstract' is used, too). This could have values like 'SINGLE_TABLE', 'JOINED' or 'MAPPED_SUPERCLASS'.

        Activity

        Hide
        Mike J added a comment -

        Good question. I had only thought of using @MappedSuperclass on an abstract class, but that was just for clarity and by convention. It may well make sense to use it on a concrete class in some cases.

        The MappedSuperclass java doc even provides an example of this:

        http://java.sun.com/javaee/6/docs/api/javax/persistence/MappedSuperclass.html

        Show
        Mike J added a comment - Good question. I had only thought of using @MappedSuperclass on an abstract class, but that was just for clarity and by convention. It may well make sense to use it on a concrete class in some cases. The MappedSuperclass java doc even provides an example of this: http://java.sun.com/javaee/6/docs/api/javax/persistence/MappedSuperclass.html
        Hide
        Ben Alex added a comment -

        SVN rev 362 now incorporates further changes.

        A sample script that has tests pass is shown below:

        project com.foo
        persistence setup --provider OPENJPA --database HYPERSONIC_IN_MEMORY 
        
        entity --name ~.Food --mappedSuperclass
        field string --fieldName description --notNull
        
        entity --name ~.Drink --extends ~.Food  --testAutomatically
        field number --fieldName ml --type java.lang.Integer --notNull
        
        entity --name ~.Party --inheritanceType SINGLE_TABLE --abstract
        field string --fieldName fullName --notNull
        
        entity --name ~.Person --extends ~.Party  --testAutomatically
        field string --fieldName firstName --notNull
        field string --fieldName lastName --notNull
        
        perform eclipse
        perform tests
        

        I decided against the Roo commands offering advanced configuration options with respect to identifying the @DiscriminatorColumn and @DiscriminatorValue. The "entity" command was already quite complicated and now it is even more so due to the provision of these inheritance configuration features (specifically there is now a --inheritanceType and --mappedSuperclass option) and we need to draw the line somewhere given Roo is about convention over configuration. Of course it's possible to edit the resulting .java files and add any additional annotations desired if the defaults (as described at http://java.sun.com/javaee/6/docs/api/javax/persistence/DiscriminatorColumn.html) are unacceptable. In due course we'll also have Spring Shell separated out and provide text editing commands that can be incorporated into scripts, in the spirit of *nix tools like sed.

        Note that if your @Entity has @MappedSuperclass, Hibernate throws a java.lang.AssertionError from AnnotationBinder.java:817 when executing with JDK 5+ assertions enabled. Because Maven (and "perform tests") executes with assertions enabled by default, the tests will fail in this case. However, they will pass by default in Eclipse as it defaults to not executing the assertions. You can see the failure in Eclipse by add the "-ea" JVM argument when invoking the tests within Eclipse. I do not consider there anything wrong with the code Roo produces given it complies with the @MappedSuperclass JavaDocs and executes fine with OpenJPA (as trying the above sample script reveals).

        Any further comments on this are welcome.

        Show
        Ben Alex added a comment - SVN rev 362 now incorporates further changes. A sample script that has tests pass is shown below: project com.foo persistence setup --provider OPENJPA --database HYPERSONIC_IN_MEMORY entity --name ~.Food --mappedSuperclass field string --fieldName description --notNull entity --name ~.Drink -- extends ~.Food --testAutomatically field number --fieldName ml --type java.lang. Integer --notNull entity --name ~.Party --inheritanceType SINGLE_TABLE -- abstract field string --fieldName fullName --notNull entity --name ~.Person -- extends ~.Party --testAutomatically field string --fieldName firstName --notNull field string --fieldName lastName --notNull perform eclipse perform tests I decided against the Roo commands offering advanced configuration options with respect to identifying the @DiscriminatorColumn and @DiscriminatorValue. The "entity" command was already quite complicated and now it is even more so due to the provision of these inheritance configuration features (specifically there is now a --inheritanceType and --mappedSuperclass option) and we need to draw the line somewhere given Roo is about convention over configuration. Of course it's possible to edit the resulting .java files and add any additional annotations desired if the defaults (as described at http://java.sun.com/javaee/6/docs/api/javax/persistence/DiscriminatorColumn.html ) are unacceptable. In due course we'll also have Spring Shell separated out and provide text editing commands that can be incorporated into scripts, in the spirit of *nix tools like sed. Note that if your @Entity has @MappedSuperclass, Hibernate throws a java.lang.AssertionError from AnnotationBinder.java:817 when executing with JDK 5+ assertions enabled. Because Maven (and "perform tests") executes with assertions enabled by default, the tests will fail in this case. However, they will pass by default in Eclipse as it defaults to not executing the assertions. You can see the failure in Eclipse by add the "-ea" JVM argument when invoking the tests within Eclipse. I do not consider there anything wrong with the code Roo produces given it complies with the @MappedSuperclass JavaDocs and executes fine with OpenJPA (as trying the above sample script reveals). Any further comments on this are welcome.
        Hide
        Paul Chapman added a comment -

        When creating a sub-class of a class that has SINGLE_TABLE inheritance specified for it, then an @DiscriminatorValue annotation should be added to the sub-class at class level.

        Similarly when defining JOINED inheritance, an @PrimaryKeyJoinColumn should be added to all the sub-classes.

        Show
        Paul Chapman added a comment - When creating a sub-class of a class that has SINGLE_TABLE inheritance specified for it, then an @DiscriminatorValue annotation should be added to the sub-class at class level. Similarly when defining JOINED inheritance, an @PrimaryKeyJoinColumn should be added to all the sub-classes.
        Hide
        Nils Schmidt added a comment -

        Make sure to use a newer version of Hibernate than 3.5.1 otherwise the combination of @Entity and @MappedSuperclass results in a NullPointerException. See the bugfix here: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5125

        I would suggest to note both problems in the Roo documentation:

        • Assertion problem as described above with fix as shown in ROO-1016
        • NullPointer problem and hint to hibernate bug

        Adding it to the docs would hopefully save others time in searching for the reasons of those problems.

        Show
        Nils Schmidt added a comment - Make sure to use a newer version of Hibernate than 3.5.1 otherwise the combination of @Entity and @MappedSuperclass results in a NullPointerException. See the bugfix here: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5125 I would suggest to note both problems in the Roo documentation: Assertion problem as described above with fix as shown in ROO-1016 NullPointer problem and hint to hibernate bug Adding it to the docs would hopefully save others time in searching for the reasons of those problems.
        Hide
        Nils Schmidt added a comment -

        Okay, maybe my previous comment was to fast. Using a version newer that 3.5.1 does indeed avoid the NullPointerException but instead you get an exception telling you that using @Entity and @MappedSuperclass for the same class is not allowed.

        I could solve my problem so far by switching to OpenJPA as described by Ben. Nevertheless, I guess some investigation in this area would not be bad.

        PS: I was using Roo 1.1.0.M2 for the tests.

        Show
        Nils Schmidt added a comment - Okay, maybe my previous comment was to fast. Using a version newer that 3.5.1 does indeed avoid the NullPointerException but instead you get an exception telling you that using @Entity and @MappedSuperclass for the same class is not allowed. I could solve my problem so far by switching to OpenJPA as described by Ben. Nevertheless, I guess some investigation in this area would not be bad. PS: I was using Roo 1.1.0.M2 for the tests.

          People

          • Assignee:
            Ben Alex
            Reporter:
            Tim Schmidt
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: