Search code examples
javaoraclehibernatepaginationora-00918

Hibernate pagination ORA-00918: column ambiguously defined


When hibernate tries to paginate an entity generated using the following hbm.xml, it throws up column ambiguously defined.

<class lazy="false" dynamic-update="true" optimistic-lock="all" table="A" name="org.package.Entity">
  <cache usage="read-write"/>
  <id unsaved-value="null" type="java.lang.Long" name="aId">
    <column name="ID_A" not-null="true" sql-type="java.lang.Long"/>
    <generator class="org.package.Entity"/>
  </id>
  <property type="java.lang.Long" name="aGroupId" not-null="true">
    <column name="ID_GROUP" not-null="true" sql-type="java.lang.Long"/>
  </property>
  <property type="java.lang.String" name="statusCode" not-null="true">
    <column name="CD_STATUS" not-null="true" sql-type="char(30)" length="30"/>
  </property>
  <property type="java.lang.Long" name="templateId" not-null="false">
    <column name="ID_TEMPLATE" not-null="false" sql-type="java.lang.Long"/>
  </property>

  <many-to-one name="aGroup" cascade="none" column="Id_Group" 
      class="org.package.Entity"
      insert="false" update="false"/>
  <many-to-one name="template" cascade="none" column="ID_TEMPLATE" 
      class="org.package.Entity"
      insert="false" update="false"/>
</class>

What is wrong with this entity definition?

Edit: Turning it into QandA format.


Solution

  • ID_TEMPLATE is being condensed into one column in the query, ID_GROUP isn't.

    Hibernate uses a direct string comparison to see if two properties depend on the same column. This is case sensitive, so ID_GROUP was being selected a second time as Id_Group.

    Changing the cases to match, it worked.

    <class lazy="false" dynamic-update="true" optimistic-lock="all" table="A" name="org.package.Entity">
      <cache usage="read-write"/>
      <id unsaved-value="null" type="java.lang.Long" name="aId">
        <column name="ID_A" not-null="true" sql-type="java.lang.Long"/>
        <generator class="org.package.Entity"/>
      </id>
      <property type="java.lang.Long" name="aGroupId" not-null="true">
        <column name="ID_GROUP" not-null="true" sql-type="java.lang.Long"/>
      </property>
      <property type="java.lang.String" name="statusCode" not-null="true">
        <column name="CD_STATUS" not-null="true" sql-type="char(30)" length="30"/>
      </property>
      <property type="java.lang.Long" name="templateId" not-null="false">
        <column name="ID_TEMPLATE" not-null="false" sql-type="java.lang.Long"/>
      </property>
    
      <many-to-one name="aGroup" cascade="none" column="ID_GROUP" 
          class="org.package.Entity"
          insert="false" update="false"/>
      <many-to-one name="template" cascade="none" column="ID_TEMPLATE" 
          class="org.package.Entity"
          insert="false" update="false"/>
    </class>
    

    Maintaining old code is fun. Hope this helps someone.