AttributeConverter for Enum within JPQL query

Description

After upgrade Hibernate ORM from 5.0.2 to 5.0.3 I can't make to work JPQL query which uses Enum value with AttributeConverter as part of WHERE clause.

Given this classes:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 package point.data.jpa.entities; public class DeskTransaction { public enum Type { TYPE1(1), TYPE2(2); private int code; private static Map<Integer, Type> typesByCode = new HashMap<>(); static { for (Type type : Type.values()) { typesByCode.put(type.code, type); } } public Type(int code) { this.code = code; } public int code getCode() { return this.code; } public static Type fromCode(int code) { return typesByCode.get(code); } } @Converter(autoApply = true) public static class TypeConverter implements AttributeConverter<Type, Integer> { @Override public Integer convertToDatabaseColumn(Type attribute) { return attribute == null ? null : attribute.getCode(); } @Override public Type convertToEntityAttribute(Integer dbData) { return dbData == null ? null : Type.fromCode(dbData); } } @Column(nullable = false) private Type type; @ManyToOne(optional = true) @JoinColumn(name = "worker_id") private Employee employee; @Column(name = "money", nullable = false) private BigDecimal sum; // getters and setters }

Before 5.0.3 (up to 5.0.2 inclusive) this JPQL query works (in 4.x it also worked fine):
SELECT dt.employee, -SUM(dt.sum) FROM point.data.jpa.entities.DeskTransaction dt WHERE dt.type = 1 GROUP BY dt.employee

After upgrading to 5.0.3 it don't work anymore and raises exception at application launch:

1 Caused by: org.hibernate.QueryException: AttributeConverter domain-model attribute type [point.data.jpa.entities.DeskTransaction$Type] did not match query literal type [java.lang.Integer]

I think that before 5.0.3 AttributeConverters were not applied for this JPQL WHERE clause so literal "1" worked because in DB this is INTEGER field. So I tried to replace literal "1" to Enum in this query.

I tried this:
SELECT dt.employee, -SUM(dt.sum) FROM point.data.jpa.entities.DeskTransaction dt WHERE dt.type = TYPE1 GROUP BY dt.employee
In this case application starts fine but when this query executes it raises the exception:

1 2 Column "TYPE1" not found; SQL statement: select desktransa0_.worker_id as col_0_0_, -sum(desktransa0_.money) as col_1_0_, employee1_.id as id1_30_, employee1_.enable_adminka as enable_a2_30_, employee1_.enable_switch as enable_s3_30_, employee1_.enable_vpn as enable_v4_30_, employee1_.active as active5_30_, employee1_.birthday as birthday6_30_, employee1_.firstname as firstnam7_30_, employee1_.lastname as lastname8_30_, employee1_.login as login9_30_, employee1_.password as passwor10_30_, employee1_.patronymic as patrony11_30_, employee1_.position as positio12_30_, employee1_.com_config_notifications as com_con13_30_, employee1_.ip_address as ip_addr14_30_ from buhuchet desktransa0_ inner join workers employee1_ on desktransa0_.worker_id=employee1_.id where desktransa0_.type=TYPE1 and (desktransa0_.worker_id is not null) group by desktransa0_.worker_id [42122-190]

(take no note of additional fields as my real DeskTransaction and Employee classes are little bigger)

The real problem here is desktransa0_.type=TYPE1. Of course this is not correct SQL.

Then I tried to wrote full qualified class name for enum:
SELECT dt.employee, -SUM(dt.sum) FROM point.data.jpa.entities.DeskTransaction dt WHERE dt.type = point.data.jpa.entities.DeskTransaction.Type.TYPE1 GROUP BY dt.employee

This causes exception:

1 Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: 'point.data.jpa.entities.DeskTransaction.Type.TYPE1' [SELECT dt.employee, -SUM(dt.sum) FROM point.data.jpa.entities.DeskTransaction dt WHERE dt.type = point.data.jpa.entities.DeskTransaction.Type.TYPE1 AND dt.employee IS NOT NULL GROUP BY dt.employee]

Then I changed nested class divider from dot to "$" sign:
SELECT dt.employee, -SUM(dt.sum) FROM point.data.jpa.entities.DeskTransaction dt WHERE dt.type = point.data.jpa.entities.DeskTransaction$Type.TYPE1 GROUP BY dt.employee

And finally it works fine!

I find this last solution while wroting this report and now not sure if it is bug at all. Maybe wroting nested classes in class-loader format with "$" as divider is right solution?

But even if this is true then when this has been changed? I check all changes between 5.0.2 and 5.0.3 and found only HHH-9074. But it is for boolean and not enums.

Maybe it should be documented somewhere as many JPQL queries became broken after upgrading to 5.0.3. I think it is bug that type = 1 worked before (skipping AttributeConverters) but it worked quite a while...

And maybe it is possible to make type = TYPE1 (without FQCN) also works? If class of type is known at runtime then we can deduce enum class for TYPE1.

Environment

Ubuntu 12.04 x64 / Spring 4.2 / Hibernate 5.0.3

Status

Assignee

Steve Ebersole

Reporter

Ruslan Stelmachenko

Fix versions

Labels

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Affects versions

5.0.3

Priority

Major