| Finding the cause of this problem took me a lot of time, because unfortunately Hibernate was not helping me find the problem in the HQL. Now I want to help you track this insidious issue Description of context I need to bulk delete entities based on a where condition. Nothing esoteric. But the column I am querying is based on a formula expression. In fact, for all of my linked entities I perform a double-mapping, as the handwritten example below.
class Entity{
@onetomany
@joincolumn("roleid")
private Role role;
@formula("roleid")
@private final String roleId = null;
}
class Role {
@id@column("roleid")
private String id;
}
The following HQL does not work:
delete from com.acme.Entity item where item.roleId in (...)
However, navigating the relationship works
delete from com.acme.Entity item where item.role.id in (...)
Stack trace:
java.lang.NullPointerException
at org.hibernate.internal.util.StringHelper.join(StringHelper.java:49) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.hql.internal.ast.tree.DotNode.initText(DotNode.java:251) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.hql.internal.ast.tree.DotNode.resolve(DotNode.java:244) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:109) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:104) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.hql.internal.ast.HqlSqlWalker.resolve(HqlSqlWalker.java:1013) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.expr(HqlSqlBaseWalker.java:1286) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.exprOrSubquery(HqlSqlBaseWalker.java:4713) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.comparisonExpr(HqlSqlBaseWalker.java:4497) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2130) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2055) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:813) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.deleteStatement(HqlSqlBaseWalker.java:455) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:275) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:262) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:190) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:142) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:302) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:240) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1907) ~[hibernate-core-5.1.0.Final.jar:5.1.0.Final]
at com.acme.Dao.deleteAll
Comment I want to report this as a bug because IMO the behaviour between select and delete is inconsistent (just replace "delete" with "from" keyword in the HQL and you get a query) AND because NPE is really really nasty, doesn't help you understand why the code failed, only that it failed for some reason. I don't see any reason to reject DELETEs based on the value of a Formula, especially if the formula reduces itself to a column and not a "real" formula. I would like to provide a test case but I am still new in reporting issues to Hibernate |