After upgrading from 5.2.12 to hibernate 5.3.4, the Hibernate ColumnTransformer stopped working
I have an entity class with a field annotated with @ColumnTransformer
@NotNull
@Column(name = "CURRENCY_CODE_ID")
@ColumnTransformer(
read = "(SELECT cc.code FROM currency_code AS cc WHERE cc.currency_code_id = currency_code_id)",
write = "(COALESCE((SELECT cc.currency_code_id FROM currency_code AS cc WHERE cc.code = ?),0))")
public String currency;
In hibernate
5.2.12 it worked fine, but after upgrading to hibernate 5.3.4.Final it suddenly crashed and I was generating the following query
campaign0_.campaign_group_id as campaign3_33_,
(SELECT cc.code FROM public.currency_code AS cc
WHERE cc.campaign0_.currency_code_id = campaign0_.currency_code_id) as currency4_33_,
campaign0_.date_created as date_cre5_33_,
So in the where clause, cc.currency_code_id = currency_code_id is replaced with cc.campaign0_.currency_code_id 。 So basically the generated table name campaign0_ is injected between the alias and column name of the table. Not sure how it happened and what the workaround was. I did search but so far nothing.
There
is also no mention in the migration guide – https://github.com/hibernate/hibernate-orm/blob/5.3/migration-guide.adoc
Solution
Finally, after a lot of debugging and research, I found the bug reported for the 5.* release series – https://hibernate.atlassian.net/browse/HHH-8944?page=com.atlassian.jira.plugin.system.issuetabpanels%3Aall-tabpanel
Looks like I have to use the forColumn configuration, I tried it and it worked, but it’s a bit weird. Work from multiple combinations of capitalization
@NotNull
@Column(name = "CURRENCY_CODE_ID")
@ColumnTransformer(
forColumn = "CURRENCY_CODE_ID",
read = "(SELECT cc.code FROM currency_code AS cc WHERE cc.CURRENCY_CODE_ID = currency_code_id)",
write = "(COALESCE((SELECT cc.currency_code_id FROM currency_code AS cc WHERE cc.code = ?),0))")
public String currency;
As you can see, I added forColumn = “CURRENCY_CODE_ID” as capitalization and cc.CURRENCY_CODE_ID as uppercase, so it skipped it. So the behavior is still a bit quirky m but works in the list
The result of the resulting is
(SELECT
cc.code
FROM
public.currency_code AS cc
WHERE
cc.CURRENCY_CODE_ID = campaign0_.currency_code_id) as currency4_33_,
This also works, so it looks like a caps issue. The witch saved me
@NotNull
@Column(name = "currency_code_id")
@ColumnTransformer(
forColumn = "currency_code_id",
read = "(SELECT cc.code FROM currency_code AS cc WHERE cc.CURRENCY_CODE_ID = currency_code_id)",
write = "(COALESCE((SELECT cc.currency_code_id FROM currency_code AS cc WHERE cc.code = ?),0))")
public String currency;