Hibernate 6 is selecting extra columns on a joined table strategy when specifying the parent class in the query. When there is a large hierarchy, it causes an error when it exceeds 1664 columns (Postgres). Is there any configuration change to make it to avoid selecting all these unnecessary columns?
This also makes eager loading not work in the parent class with a large hierarchy.
In this example with A being the parent, and B, C, D are joined tables.
Getting one of the subclasses D, but passing in the superclass:
Example query:
session.get(A.class, id);
Generated SQL:
hibernate 6.1.7:
select a1_0.ID,a1_0.DISCRIMINATOR,a1_0.FIELDA,a1_0.PARENTID,a1_1.FIELDB,a1_2.FIELDC,a1_3.FIELDD from A a1_0 left join B a1_1 on a1_0.ID=a1_1.ID left join C a1_2 on a1_0.ID=a1_2.ID left join D a1_3 on a1_0.ID=a1_3.ID where a1_0.ID=?
hibernate 5.5.3:
select a0_.ID as id1_0_0_, a0_.FIELDA as fielda3_0_0_, a0_.PARENTID as parentid4_0_0_, a0_.DISCRIMINATOR as discrimi2_0_0_ from A a0_ where a0_.ID=?
select a_3_.FIELDD as fieldd2_24_ from D a_3_ where a_3_.ID=?
This example hierarchy is mixed with a discriminator using XML, but the same behavior was seen with a pure joined table strategy as well.
XML Files:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="test">
<class name="A" table="A" dynamic-insert="true" dynamic-update="true" select-before-update="true" discriminator-value="A">
<cache usage="read-write"/>
<id name="id" column="ID">
<generator class="increment"/>
</id>
<discriminator column="DISCRIMINATOR" type="string" length="30"/>
<property name="fielda" type="string" column="FIELDA" length="100" />
<many-to-one name="parentId" column="PARENTID" class="A" lazy="false"/>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<subclass name="test.B" extends="test.A" dynamic-insert="true" dynamic-update="true" select-before-update="true" discriminator-value="B">
<join table="B" fetch="select">
<key on-delete="cascade">
<column name="ID"/>
</key>
<property name="fieldb" type="string" column="FIELDB" length="100"/>
</join>
</subclass>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<subclass name="test.C" extends="test.A" dynamic-insert="true" dynamic-update="true" select-before-update="true" discriminator-value="C">
<join table="C" fetch="select">
<key on-delete="cascade">
<column name="ID"/>
</key>
<property name="fieldc" type="string" column="FIELDC" length="100"/>
</join>
</subclass>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<subclass name="test.D" extends="test.A" dynamic-insert="true" dynamic-update="true" select-before-update="true" discriminator-value="D">
<join table="D" fetch="select">
<key on-delete="cascade">
<column name="ID"/>
</key>
<property name="fieldd" type="string" column="FIELDD" length="100"/>
</join>
</subclass>
</hibernate-mapping>
JAVA Classes:
package test;
public class A {
private String fielda;
private Long id;
private A parentId;
...
}
package test;
public class B extends A {
private String fieldb;
...
}
package test;
public class C extends A {
private String fieldc;
...
}
package test;
public class D extends A {
private String fieldd;
...
}