Select query containing composite key in Hibernate 6 causes H2 error in Oracle compatibility mode

We are currently migrating from Hibernate 5.6 to Hibernate 6.2. We have a composite key defined using the @IdClass strategy as follows:

public class DuesReportCorrelationId implements Serializable {

    private static final long serialVersionUID = 1L;

    private String annex;

    private String itemCeCode;

    public DuesReportCorrelationId() {
    }

    public DuesReportCorrelationId(String annex, String itemCeCode) {
        this.annex = annex;
        this.itemCeCode = itemCeCode;
    }

    // Getters and Setters
    public String getAnnex() {
        return annex;
    }

    public void setAnnex(String annex) {
        this.annex = annex;
    }

    public String getItemCeCode() {
        return itemCeCode;
    }

    public void setItemCeCode(String itemCeCode) {
        this.itemCeCode = itemCeCode;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        DuesReportCorrelationId that = (DuesReportCorrelationId) o;
        return Objects.equals(annex, that.annex) && Objects.equals(itemCeCode, that.itemCeCode);
    }

    @Override
    public int hashCode() {
        return Objects.hash(annex, itemCeCode);
    }
}


@Entity
@Table(name = "DUES_REPORT_CORRELATION")
@IdClass(DuesReportCorrelationId.class)
public class DuesReportCorrelation {

    @Id
    @Column(name = "ANNEX", nullable = false)
    @NotNull
    @Size(min = 1, max = 2)
    private String annex;


    @Column(name = "REF_CODE", nullable = false)
    @NotNull
    @Size(min = 1, max = 4)
    private String refCode;

    @Column(name = "ITEM_TYPE", nullable = false)
    @NotNull
    @Size(min = 1, max = 100)
    private String itemType;

    @Id
    @Column(name = "ITEM_CE_CODE", nullable = false)
    @NotNull
    @Size(min = 1, max = 12)
    private String itemCeCode;


    public DuesReportCorrelation() {
    }

    public DuesReportCorrelation(String annex, String refCode, String itemType, String itemCeCode) {
        this.annex = annex;
        this.refCode = refCode;
        this.itemType = itemType;
        this.itemCeCode = itemCeCode;
    }

    public String getAnnex() {
        return annex;
    }

    public void setAnnex(String annex) {
        this.annex = annex;
    }

    public String getRefCode() {
        return refCode;
    }

    public void setRefCode(String refCode) {
        this.refCode = refCode;
    }

    public String getItemType() {
        return itemType;
    }

    public void setItemType(String itemType) {
        this.itemType = itemType;
    }

    public String getItemCeCode() {
        return itemCeCode;
    }

    public void setItemCeCode(String itemCeCode) {
        this.itemCeCode = itemCeCode;
    }

}

The query constructed in Hibernate 5 is:

select 
        duesreport0_.ANNEX as annex1_27_,
        duesreport0_.ITEM_CE_CODE as item_ce_2_27_,
        duesreport0_.REF_CODE as ref_code3_27_,
        duesreport0_.ITEM_TYPE as item_typ4_27_ 
    from
        DUES_REPORT_CORRELATION duesreport0_ 
    where
        (
            duesreport0_.ANNEX, duesreport0_.ITEM_CE_CODE
        ) in (
            select
                distinct duesreport1_.ANNEX,
                duesreport1_.ITEM_CE_CODE 
            from
                DUES_REPORT_CORRELATION duesreport1_ 
            where
                1=1
        ) 
    order by
        duesreport0_.ANNEX,
        duesreport0_.ITEM_CE_CODE limit ? 

as opposed to the following Hibernate 6 version which encapsulates the composite key fields within parentheses:

select d1_0.ANNEX,d1_0.ITEM_CE_CODE,d1_0.ITEM_TYPE,d1_0.REF_CODE from DUES_REPORT_CORRELATION d1_0 
where (d1_0.ANNEX,d1_0.ITEM_CE_CODE) in(select distinct (d2_0.ANNEX,d2_0.ITEM_CE_CODE) 
										from DUES_REPORT_CORRELATION d2_0 where 1=1) 
order by d1_0.ANNEX,d1_0.ITEM_CE_CODE offset ? rows fetch first ? rows only

causing an H2 exception:
org.h2.jdbc.JdbcSQLSyntaxErrorException: Column count does not match

However, the query constructed is syntactically incorrect also in Oracle:
ORA-00920: invalid relational operator

I tried switching to the Embeddable strategy but the problem persists.

Could you please offer some insight?
Thank you in advance.

Which database and dialect are you using?

Hello Marco,
thank for your reply.
We’re using Oracle 19 and H2Dialect.

Use the OracleDialect. Using H2Dialect as the name implies is only supported for the H2 database.

Hello Christian,
thank you for your reply.
But it is an H2 database in Oracle compatibility mode and there were no issues with the previous versions of Hibernate.
As far as I can tell, the problem for us is in the visitSqlSelections method of the H2SqlAstTranslator class.
If the IF clauses were enriched with an additional check for DISTINCT the matter would be resolved.
Nonetheless, I will try your recommendation.

Hello again,
your suggestion worked like a charm. You’re a champ!
Regards,
Giorgos

But it is an H2 database in Oracle compatibility mode and there were no issues with the previous versions of Hibernate.

Then why do you write that you’re using Oracle 19? Hibernate ORM does not support H2 configured in a compatibility mode, because these modes are broken by design. If you use Oracle in your production environment, don’t use H2 for testing. Start a real Oracle database and test against that. It will spare you a lot of pain and surprises at production time.

You have a point, it will solve several issues but it has other complexities. We’re thinking of using Testcontainers.