Issue with BooleanConverter in Postgres with smallint

Hello,

The issue appeared with HHH-16125 remove DDL generation stuff from converters.

Because our Boolean Converter is typed as boolean.

But for Postgres, it is actually stored as a smallint, similar to Oracle, which doesn’t have a boolean type but uses a number. Currently, we are coexisting with both database management systems as we are in the process of migration. It might be a future project to switch boolean types to the boolean type in the PG database, but it’s not the case yet.

So, I had to adapt the JDBC type for booleans specifically for PG by treating them as SmallIntJdbcType.

The issue is that the new method BooleanJavaType#getCheckCondition assumes that the BooleanConverter returns an integer and attempts to invoke longValue() on it, which raises an exception.

The solution I’ve found for now is to override it, specifying that the Converter indeed returns a Boolean type.

And to pass this custom type to the TypeIntegrator.

I tried converting the BooleanConverter to <Boolean, Byte> or <Boolean, Short>, but this is incorrect for Oracle and causes inverse problems. Also, there is no possibility to use one Converter for Oracle and another for Postgres, at least I haven’t found a way.

What do you think?

Why don’t you just set the hibernate.type.preferred_boolean_jdbc_type property to smallint?

Indeed, it’s better than my override of the Dialect. I had already used it, but I had set it to BIT.

Unfortunately, it doesn’t solve the issue of the converter being treated as an integer with the SmallIntJdbcType => BooleanJavaType#getCheckCondition

Why do you need the converter? Just remove it, no?

It is only used to handle nullity.

I will check with the person who implemented it about the specific case they encountered, and I will try to remove it.
Indeed, that would solve our problem definitively. ^^
I assume they had a good reason, but let’s see if we can resolve it differently.

In our framework, boolean management is nullsafe, so apparently, this is not the case for Hibernate (see stack trace). This is to handle cases of creation through scripts, for example, where values might be null instead of false.

I have searched for another solution to make it nullsafe without using a converter, but I haven’t found anything simple.

You mean that you use a primitive boolean in your entity model and want null from the database to be interpreted as false? That sounds very weird to me. Why not use Boolean then? Or make the column in the database not null and set existing null columns to false?
If you really must, you can register a custom BooleanJavaType that implements wrap in a way that never passes through null but rather defaults to false.
I would strongly recommend you to fix your data model though as querying might just get more complicated with nulls involved.

Yes, it’s a primitive boolean in the data model, but we don’t want to handle nullability. It’s just like how we use smallint in PostgreSQL and number in Oracle; we encounter cases of nullability.

So, we use this converter to translate nulls in the database to false in the data model, to overcome this issue. In the medium term, we will transition to a boolean type in the PostgreSQL database, and we won’t have this problem anymore.

image

image