7 Replies Latest reply on Mar 14, 2013 2:39 AM by johnqcitizen

    Getting "association error" when reverse-engineering an existing schema with Hibernate tools

    johnqcitizen

      I'm connecting to a production Oracle 10g database and attempting to generate a Hibernate configuration file using the hibernate3-maven-plugin running in Maven.

       

      However when I run the hibernate3:hbm2java goal I get the following error: An association from the table FOO refers to the unmapped class com.whatever.domain.Bar

       

      My maven project file looks like this:

       

      <plugin>

        <groupId>org.codehaus.mojo</groupId>

        <artifactId>hibernate3-maven-plugin</artifactId>

        <version>2.2</version>

        <configuration>

          <components>

            <component>

              <name>hbm2java</name>

              <implementation>jdbcconfiguration</implementation>

              <outputDirectory>target/classes</outputDirectory>

            </component>

          </components>

          <componentProperties>

            <propertyfile>src/main/resources/hibernate.properties</propertyfile>

          </componentProperties>

        </configuration>

        <dependencies>

          <dependency>

            <groupId>com.oracle</groupId>

            <artifactId>ojdbc</artifactId>

            <version>11.1.0.6.0</version>

          </dependency>

          <dependency>

            <groupId>cglib</groupId>

            <artifactId>cglib-nodep</artifactId>

            <version>2.1_3</version>

          </dependency>

        </dependencies>

      </plugin>

       

      My hibernate.properties file contains the following:

       

      hibernate.connection.driver_class=oracle.jdbc.driver.OracleDriver

      hibernate.connection.url=jdbc:oracle:thin:@<server>:<host>:<db>

      hibernate.connection.username=<username>

      hibernate.connection.password=<password>

      hibernate.dialect=org.hibernate.dialect.Oracle10gDialect

      hibernate.default_schema=<schema>

       

      Because this is a production database, then I assume that the schema is sound and expect the hibernate3-maven-plugin to extract that schema and generate annotated java files without error.

       

      I've narrowed down the offending tables to the following:

       

        FOO

          - foreign key 'a' in BAR

          - foreign key 'b' in BAR

          - foreign key 'c' in QUUX

          - primary key is composite of foreign keys 'a', 'b' in BAR and foreign key 'c' in QUUX

       

       

        BAR

          - foreign key 'a' in BAZ

          - foreign key 'b' in QUX

          - primary key is a composite of the foreign key 'a' in BAZ and foreign key 'b' in QUX

       

       

        BAZ

        - primary key 'a'

        - no foreign keys

       

       

        QUX

        - primary key 'b'

        - no foreign keys

       

        QUUX

        - primary key 'c'

        - no foreign keys

       

       

      If I specify the tables FOO, BAR and BAZ in a reveng.xml file, then the hbm2java goal is successful. If I specify the tables FOO, BAR, and QUX in a reveng.xml file, then the hbm2java goal is successful. But if tables FOO, BAR, BAZ, and QUX are specified then the hbm2java goal fails with the aforementoned association error between FOO and com.whatever.domain.Bar file. That is, if both tables representing the foreign keys in BAR are present, then the goal fails. If just one foreign key table is present, then the goal succeeds.

       

      Any suggestions on what is causing the problem, and how to fix it?

        • 1. Re: Getting "association error" when reverse-engineering an existing schema with Hibernate tools
          maxandersen

          Could you show the actual error/stacktrace ?

           

          p.s. the hbm2java maven goals are not maintained by us; thus could you please tell what version of hibernate tools it is actually using ?

          • 2. Re: Getting "association error" when reverse-engineering an existing schema with Hibernate tools
            johnqcitizen

            Thanks for the response.

             

            I am using maven-hibernate3-plugin 2.2, which has a dependency on hibernate-tools  3.2.3.GA and hibernate-core 3.3.1.GA

             

            Here is some output from running the following command:

             

            $ mvn -X hibernate3:hbm2java

             

            Apache Maven 3.0.4 (r1232337; 2012-01-17 18:44:56+1000)

            Maven home: C:\dev\apache-maven-3.0.4\bin\..

            Java version: 1.6.0_38, vendor: Sun Microsystems Inc.

            OS name: "windows xp", version: "5.1", arch: "x86", family: "windows"

             

            [INFO] --- hibernate3-maven-plugin:2.2:hbm2java (default-cli) @ foo ---

            [DEBUG] org.codehaus.mojo:hibernate3-maven-plugin:jar:2.2:

            [DEBUG]    cglib:cglib-nodep:jar:2.2.2:runtime

            [DEBUG]    com.oracle:ojdbc:jar:11.1.0.6.0:runtime

            [DEBUG]    log4j:log4j:jar:1.2.14:runtime

            [DEBUG]    org.hibernate:hibernate-tools:jar:3.2.3.GA:compile

            [DEBUG]       org.beanshell:bsh:jar:2.0b4:compile

            [DEBUG]       freemarker:freemarker:jar:2.3.8:compile

            [DEBUG]       org.hibernate:jtidy:jar:r8-20060801:compile

            [DEBUG]    org.hibernate:hibernate-core:jar:3.3.1.GA:compile

            [DEBUG]       antlr:antlr:jar:2.7.6:compile

            [DEBUG]       commons-collections:commons-collections:jar:3.1:compile

            [DEBUG]       dom4j:dom4j:jar:1.6.1:compile

            [DEBUG]       org.slf4j:slf4j-api:jar:1.5.6:runtime (scope managed from compile) (version managed from 1.5.2)

            [DEBUG]    org.codehaus.mojo.hibernate3:maven-hibernate3-api:jar:2.2:compile

            [DEBUG]       xml-apis:xml-apis:jar:1.0.b2:compile

            [DEBUG]       org.apache.geronimo.specs:geronimo-jta_1.0.1B_spec:jar:1.1.1:runtime

            [DEBUG]       org.slf4j:slf4j-log4j12:jar:1.5.6:runtime

            [DEBUG]       org.slf4j:jcl-over-slf4j:jar:1.5.6:runtime

            [DEBUG]       org.codehaus.plexus:plexus-utils:jar:1.5.6:compile

            [DEBUG]    org.apache.maven:maven-model:jar:2.0.6:compile

            [DEBUG]    org.apache.maven:maven-project:jar:2.0.6:compile

            [DEBUG]       org.apache.maven:maven-settings:jar:2.0.6:compile

            [DEBUG]       org.apache.maven:maven-profile:jar:2.0.6:compile

            [DEBUG]       org.apache.maven:maven-artifact-manager:jar:2.0.6:compile

            [DEBUG]          org.apache.maven:maven-repository-metadata:jar:2.0.6:compile

            [DEBUG]       org.apache.maven:maven-plugin-registry:jar:2.0.6:compile

            [DEBUG]       org.apache.maven:maven-artifact:jar:2.0.6:compile

            [DEBUG]       org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile

            [DEBUG]          junit:junit:jar:3.8.2:test (scope managed from compile) (version managed from 3.8.1)

            [DEBUG]          classworlds:classworlds:jar:1.1-alpha-2:compile

            [DEBUG]    org.apache.maven:maven-plugin-api:jar:2.0.6:compile

            [DEBUG]    org.codehaus.mojo.hibernate3:maven-hibernate3-jdk14:jar:2.2:compile

            [DEBUG]    org.codehaus.mojo.hibernate3:maven-hibernate3-jdk15:jar:2.2:compile

            [DEBUG]       org.hibernate:hibernate-entitymanager:jar:3.4.0.GA:compile

            [DEBUG]          org.hibernate:hibernate-commons-annotations:jar:3.1.0.GA:compile

            [DEBUG]          javax.transaction:jta:jar:1.1:compile

            [DEBUG]       org.hibernate:ejb3-persistence:jar:1.0.2.GA:compile

            [DEBUG]       org.hibernate:hibernate-annotations:jar:3.4.0.GA:compile

            [DEBUG]       jboss:jboss-common:jar:4.0.2:compile

            [DEBUG]          slide:webdavlib:jar:2.0:compile

            [DEBUG]          xerces:xercesImpl:jar:2.6.2:compile

            [DEBUG]       javassist:javassist:jar:3.4.GA:compile

             

            [DEBUG] Goal:          org.codehaus.mojo:hibernate3-maven-plugin:2.2:hbm2java (default-cli)

            [DEBUG] Style:         Regular

            [DEBUG] Configuration: <?xml version="1.0" encoding="UTF-8"?>

            <configuration>

              <componentProperties>

                <revengfile>/src/main/resources/reveng.xml</revengfile>

                <propertyfile>src/main/resources/hibernate.properties</propertyfile>

                <packagename>com.whatever.domain</packagename>

                <jdk5>true</jdk5>

                <ejb3>true</ejb3>

              </componentProperties>

              <components>

                <component>

                  <name>hbm2java</name>

                  <implementation>jdbcconfiguration</implementation>

                  <outputDirectory>target/generated-sources/hibernate3</outputDirectory>

                </component>

              </components>

            </configuration>

            [DEBUG] =======================================================================

            [INFO]

            [INFO] >>> hibernate3-maven-plugin:2.2:hbm2java (default-cli) @ foo >>>

             

            09:06:58,296        DEBUG DriverManagerConnectionProvider:138 - created connection to: jdbc:oracle:thin:@***, Isolation Level: 2

            09:06:58,296         INFO SettingsFactory:116 - RDBMS: Oracle, version: Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production

            With the Partitioning, OLAP and Data Mining options

            09:06:58,296         INFO SettingsFactory:117 - JDBC driver: Oracle JDBC driver, version: 11.1.0.6.0-Production

            09:06:58,312         INFO Dialect:175 - Using dialect: org.hibernate.dialect.Oracle10gDialect

            09:06:58,328         INFO TransactionFactoryFactory:59 - Using default transaction strategy (direct JDBC transactions)

            09:06:58,343         INFO SettingsFactory:170 - Automatic flush during beforeCompletion(): disabled

            09:06:58,343         INFO SettingsFactory:174 - Automatic session close at end of transaction: disabled

            09:06:58,343         INFO SettingsFactory:181 - JDBC batch size: 15

            09:06:58,343         INFO SettingsFactory:184 - JDBC batch updates for versioned data: disabled

            09:06:58,343         INFO SettingsFactory:189 - Scrollable result sets: enabled

            09:06:58,343        DEBUG SettingsFactory:193 - Wrap result sets: disabled

            09:06:58,343         INFO SettingsFactory:197 - JDBC3 getGeneratedKeys(): disabled

            09:06:58,343         INFO SettingsFactory:205 - Connection release mode: auto

            09:06:58,343         INFO SettingsFactory:223 - Default schema: MY_SCHEMA

            09:06:58,343         INFO SettingsFactory:232 - Default batch fetch size: 1

             

            [ERROR] Failed to execute goal org.codehaus.mojo:hibernate3-maven-plugin:2.2:hbm2java (default-cli) on project foo: Execution default-cli of goal org.codehaus.mojo:hibernate3-maven-plugin:2.2:hbm2java failed: An association from the table FOO refers to an unmapped class: com.whatever.domain.Bar -> [Help 1]

             

            Caused by: org.hibernate.MappingException: An association from the table FOO refers to an unmapped class: com.whatever.domain.Bar

                      at org.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:1285)

                      at org.hibernate.cfg.JDBCMetaDataConfiguration.secondPassCompileForeignKeys(JDBCMetaDataConfiguration.java:33)

                      at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1203)

                      at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1148)

                      at org.codehaus.mojo.hibernate3.configuration.AbstractComponentConfiguration.getConfiguration(AbstractComponentConfiguration.java:57)

                      at org.codehaus.mojo.hibernate3.HibernateExporterMojo.configureExporter(HibernateExporterMojo.java:200)

                      at org.codehaus.mojo.hibernate3.exporter.Hbm2JavaGeneratorMojo.configureExporter(Hbm2JavaGeneratorMojo.java:64)

                      at org.codehaus.mojo.hibernate3.HibernateExporterMojo.doExecute(HibernateExporterMojo.java:273)

                      at org.codehaus.mojo.hibernate3.HibernateExporterMojo.execute(HibernateExporterMojo.java:152)

                      at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)

                      ... 20 more

             

            I am using the following hibernate configuration:

             

            hibernate.connection.driver_class=oracle.jdbc.driver.OracleDriver

            hibernate.connection.url=jdbc:oracle:thin:@****

            hibernate.connection.username=****

            hibernate.connection.password=****

            hibernate.dialect=org.hibernate.dialect.Oracle10gDialect

            hibernate.default_schema=MY_SCHEMA

             

            and the following reverse enginerring file:

             

            <?xml version="1.0" encoding="UTF-8"?>

            <!DOCTYPE hibernate-reverse-engineering PUBLIC

              "-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN"

              "http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd" >

             

            <hibernate-reverse-engineering>

                  <schema-selection match-schema="MY_SCHEMA" />

            </hibernate-reverse-engineering>

             

             

            Hope that helps.

            • 3. Re: Getting "association error" when reverse-engineering an existing schema with Hibernate tools
              johnqcitizen

              So I decided to remove maven from the problem and wrote an ant build script that uses hibernate tools directly.

               

              But I still get the same error:

               

              Apache Ant(TM) version 1.9.0 compiled on March 5 2013


              [hibernatetool] An exception occurred while running exporter #2:hbm2java (Generates a set of .java files)

              [hibernatetool] To get the full stack trace run ant with -verbose

              [hibernatetool] org.hibernate.MappingException: An association from the table FOO refers to an unmapped class: com.whatever.domain.Bar

               

               

              BUILD FAILED

              build.xml:23: org.hibernate.MappingException: An association from the table FOO refers to an unmapped class: com.whatever.domain.Bar

                        at org.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:1285)

                        at org.hibernate.cfg.JDBCMetaDataConfiguration.secondPassCompileForeignKeys(JDBCMetaDataConfiguration.java:33)

                        at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1203)

                        at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1148)

                        at org.hibernate.tool.ant.ConfigurationTask.getConfiguration(ConfigurationTask.java:56)

                        at org.hibernate.tool.ant.HibernateToolTask.getConfiguration(HibernateToolTask.java:302)

                        at org.hibernate.tool.ant.HibernateToolTask.getProperties(HibernateToolTask.java:318)

                        at org.hibernate.tool.ant.ExporterTask.configureExporter(ExporterTask.java:94)

                        at org.hibernate.tool.ant.Hbm2JavaExporterTask.configureExporter(Hbm2JavaExporterTask.java:34)

                        at org.hibernate.tool.ant.ExporterTask.execute(ExporterTask.java:39)

                        at org.hibernate.tool.ant.HibernateToolTask.execute(HibernateToolTask.java:186)

               

              Here's my ant build.xml file:

               

              <project basedir="." default="reveng">

               

                <property name="build.dir" value="${basedir}/target" />

               

                <path id="toolslib">

                  <path location="/r/org/hibernate/hibernate-tools/3.2.3.GA/hibernate-tools-3.2.3.GA.jar" />

                  <path location="/r/org/hibernate/hibernate-core/3.3.1.GA/hibernate-core-3.3.1.GA.jar" />

                  <path location="/r/org/hibernate/hibernate-annotations/3.4.0.GA/hibernate-annotations-3.4.0.GA.jar" />

                  <path location="/r/freemarker/freemarker/2.3.8/freemarker-2.3.8.jar" />

                  <path location="/r/com/oracle/ojdbc/11.1.0.6.0/ojdbc-11.1.0.6.0.jar" />

                  <path location="/r/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar" />

                  <path location="/r/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar" />

                  <path location="/r/org/slf4j/slf4j-api/1.5.6/slf4j-api-1.5.6.jar" />

                  <path location="/r/org/slf4j/slf4j-log4j12/1.5.6/slf4j-log4j12-1.5.6.jar" />

                  <path location="/r/log4j/log4j/1.2.16/log4j-1.2.16.jar" />

                  <path location="/r/cglib/cglib/2.2.2/cglib-2.2.2.jar" />

                  <path location="/r/asm/asm/3.3.1/asm-3.3.1.jar" />

                  <path location="/r/commons-collections/commons-collections/3.1/commons-collections-3.1.jar" />

                </path>

               

                <taskdef name="hibernatetool" classname="org.hibernate.tool.ant.HibernateToolTask" classpathref="toolslib" />

               

                <target name="reveng" description="Reverse-engineer a DB schema">

                  <hibernatetool destdir="${build.dir}/generated-resources/hibernate3">

                    <jdbcconfiguration propertyfile="hibernate.properties" packagename="com.whatever.domain" revengfile="reveng.xml" />

                    <hbm2java jdk5="true" ejb3="true" />

                  </hibernatetool>

                </target>

               

              </project>

               

              It is accessing the same hibernate.properties file and reveng.xml file specified in the comment above.

               

              Hope this helps.

              • 4. Re: Getting "association error" when reverse-engineering an existing schema with Hibernate tools
                maxandersen

                what is in reveng.xml ?

                 

                Anything that could make "com.whatever.domain.Bar" not be picked up ?

                • 5. Re: Getting "association error" when reverse-engineering an existing schema with Hibernate tools
                  johnqcitizen

                  Thanks for the response.

                   

                  The reveng.xml file is shown a few posts above, but I will repeat it here:

                   

                  <?xml version="1.0" encoding="UTF-8"?>

                  <!DOCTYPE hibernate-reverse-engineering PUBLIC

                    "-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN"

                    "http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd" >

                   

                  <hibernate-reverse-engineering>

                        <schema-selection match-schema="MY_SCHEMA" />

                  </hibernate-reverse-engineering>

                   

                   

                  Note that if I modify reveng.xml to remove the table BAZ (see post #1 for relationships between tables) then the reverse engineering succeeds:

                   

                  <?xml version="1.0" encoding="UTF-8"?>

                  <!DOCTYPE hibernate-reverse-engineering PUBLIC

                    "-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN"

                    "http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd" >

                   

                  <hibernate-reverse-engineering>

                        <table-filter match-schema="MY_SCHEMA" match-name="BAZ" exclude="true"/>

                  </hibernate-reverse-engineering>

                   

                  I can also create another reveng.xml that will only reverse engineer the table BAZ. I thought that might solve my issue, but then I get other problems to do with mixing nullable and non-nullable columns when the session is created (or: when the generated classes are loaded), which I assume is a consequence of reverse-engineering one schema in two separate stages.

                   

                  But I expect that the reverse engineering of the whole schema should just work for a production database, right?

                  • 6. Re: Getting "association error" when reverse-engineering an existing schema with Hibernate tools
                    maxandersen

                    if the production database is *sane* (i.e. no weird overlapping associations, missing primary keys and foreign key funkyness) and we dont have a bug in this old version of hibernate tools

                     

                    See anything "funny" with the Baz table ?

                    • 7. Re: Getting "association error" when reverse-engineering an existing schema with Hibernate tools
                      johnqcitizen

                      See anything "funny" with the Baz table ?

                       

                      Nothing funny that I can see (but I'm not an expert). I've provided a description of the tables in post #1.

                       

                      Note that I can reverse engineer the schema if I exclude the table QUX instead of BAZ. The table FOO has two foregn keys referencing the table BAR, and the table BAR has foregn keys referencing tables BAZ and QUX. If I exclude one of BAZ or QUX, then the reverse enginneering works. If I include both, it fails.

                       

                      and we dont have a bug in this old version of hibernate tools

                       

                      I recall trying a later version of hibernate tools but got null pointer exceptions for the same configuration. I may need to read up on what's changed.