6 Replies Latest reply on Aug 13, 2008 8:13 AM by adamw

    Enver not support org.hibernate.type.MapType!

    liuxiaodu

      Found a bug in the Enver schame generation process, basically Envers dose not support org.hibernate.type.MapType. Here is the detail:

      We have entity which has a @OneToMany relationship field with the Map type:

      @OneToMany
      @JoinColumn(name="empolyee")
      @MapKey(name = "employeeType")
      private Map<EmployeeType, EmployeeIdentifier> identifiers;
      


      When I try Envers ant task, I got the following errors:

      INFO: Hibernate Validator 3.0.0.GA
      [hibernatetool] An exception occurred while running exporter #2:hbm2ddl (Generates database schema)
      [hibernatetool] To get the full stack trace run ant with -verbose
      [hibernatetool] org.hibernate.MappingException: Type not supported: org.hibernate.type.MapType
      [INFO] ------------------------------------------------------------------------
      [ERROR] BUILD ERROR
      [INFO] ------------------------------------------------------------------------
      [INFO] Error executing ant tasks
      
      Embedded error: org.hibernate.MappingException: Type not supported: org.hibernate.type.MapType
      [INFO] ------------------------------------------------------------------------
      [INFO] Trace
      org.apache.maven.lifecycle.LifecycleExecutionException: Error executing ant tasks
       at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:583)
       at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:499)
       at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:478)
       at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:330)
       at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:291)
       at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:142)
       at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:336)
       at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:129)
       at org.apache.maven.cli.MavenCli.main(MavenCli.java:287)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:597)
       at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
       at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
       at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
       at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
      Caused by: org.apache.maven.plugin.MojoExecutionException: Error executing ant tasks
       at org.apache.maven.plugin.antrun.AbstractAntMojo.executeTasks(AbstractAntMojo.java:114)
       at org.apache.maven.plugin.antrun.AntRunMojo.execute(AntRunMojo.java:83)
       at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:451)
       at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor
      .java:558)
       ... 16 more
      Caused by: org.hibernate.MappingException: Type not supported: org.hibernate.type.MapType
       at org.hibernate.tool.ant.HibernateToolTask.reportException(HibernateToolTask.java:226)
       at org.hibernate.tool.ant.HibernateToolTask.execute(HibernateToolTask.java:189)
       at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
       at org.apache.tools.ant.Task.perform(Task.java:364)
       at org.apache.tools.ant.taskdefs.Sequential.execute(Sequential.java:64)
       at net.sf.antcontrib.logic.IfTask.execute(IfTask.java:197)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:597)
       at org.apache.tools.ant.TaskAdapter.execute(TaskAdapter.java:123)
       at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
       at org.apache.tools.ant.Task.perform(Task.java:364)
       at org.apache.tools.ant.Target.execute(Target.java:341)
       at org.apache.maven.plugin.antrun.AbstractAntMojo.executeTasks(AbstractAntMojo.java:108)
       ... 19 more
      Caused by: org.hibernate.MappingException: Type not supported: org.hibernate.type.MapType
       at org.jboss.envers.metadata.VersionsMetadataGenerator.addProperties(VersionsMetadataGenerator.java:398)
       at org.jboss.envers.metadata.VersionsMetadataGenerator.generateFirstPass(VersionsMetadataGenerator.java:528)
       at org.jboss.envers.configuration.VersionsConfiguration.configure(VersionsConfiguration.java:202)
       at org.jboss.envers.configuration.VersionsConfiguration.getFor(VersionsConfiguration.java:274)
       at org.jboss.envers.ant.JPAConfigurationTaskWithEnvers.doConfiguration(JPAConfigurationTaskWithEnvers.java:33)
       at org.hibernate.tool.ant.ConfigurationTask.getConfiguration(ConfigurationTask.java:55)
       at org.hibernate.tool.ant.HibernateToolTask.getConfiguration(HibernateToolTask.java:302)
       at org.hibernate.tool.ant.Hbm2DDLExporterTask.execute(Hbm2DDLExporterTask.java:45)
       at org.hibernate.tool.ant.HibernateToolTask.execute(HibernateToolTask.java:186)
       ... 32 more
      


      Please help!

      Thanks a lot.

      Louie

        • 1. Re: Enver not support org.hibernate.type.MapType!
          liuxiaodu

          Based on the Exception, I was able to locate the root cause and try to fix it by making the following change in the following section of the code:

          org.jboss.envers.metadata.VersionsMetadataGenerator.addProperties(....)

          ...
          else if (propertyType instanceof BagType || propertyType instanceof SetType) {
           // only second pass
           if (!firstPass) {
           addOneToMany(property, currentMapper, entityName);
           }
          }
          


          I add another type MapType:

          ...
          else if (propertyType instanceof BagType || propertyType instanceof SetType || propertyType instanceof MapType) {
           // only second pass
           if (!firstPass) {
           addOneToMany(property, currentMapper, entityName);
           }
          }
          


          It looks like fix my issue.

          I would like to request your help to validate if this fix is correct. If so, we would like to see this fix in the next release since we have a lot of the @OneToMany attribute type is Map in our entities.

          Thanks for your help.

          Louie


          • 2. Re: Enver not support org.hibernate.type.MapType!
            adamw

            Hello,

            I think it may prevent the exception from being thrown when generating the schema, but the versioning won't work properly. As with many-to-many relations, this isn't supported yet (as it requires generating a "middle" table with the data).

            Again, if you can, please create a JIRA feature request to support Map-s :)

            Adam

            • 3. Re: Enver not support org.hibernate.type.MapType!
              awhitford

              I'm not following the reference to many-to-many relations.

              How is a Map significantly different from a Set at the table level? The above example is @OneToMany, so there is table A and table B. The only material difference that I see is that a Set has no @MapKey...

              I guess I just don't quite understand why Set is implemented, but a Map is not.

              • 4. Re: Enver not support org.hibernate.type.MapType!
                adamw

                Hello,

                it's different at the entity level. In a @ManyToMany, or @OneToMany relationship without an "owning" side (that is, when there is no companion @ManyToOne), or when using a map, an extra table has to be generated to hold that information. And generating a "versions extra table" is not yet implemented.

                So, Set also isn't fully implemented.

                Adam

                • 5. Re: Enver not support org.hibernate.type.MapType!
                  awhitford

                  I just discovered that the lack of Map support is a major problem for me...

                  Knowing that Map isn't supported, I just made sure that my @Entity is not @Versioned. Alas, because I have other @Versioned entities, I need to use the special Envers ant task for DDL validation, and it breaks on the Map as Louie suggested...

                  Can you please modify Envers so that only @Versioned entities are running through this special logic?

                  • 6. Re: Enver not support org.hibernate.type.MapType!
                    adamw

                    Hello,

                    sorry for the late reply, I was on vacations.

                    You can always mark only some properties of an entity as @Versioned (for example - all except the Map-typed), instead of the whole entity.

                    For unversioned entities the EnversHibernateToolTask behaves (or: should behave :) ) exactly the same as HibernateToolTask. Only entities with the @Versioned annotations are processed by the "special logic" == only for them, versions tables are created.

                    Do you see some other behaviour? If so, maybe you could give some examples which don't work?

                    Adam


                    Adam