1

Unfortunatelly I live in Belarus, domain zone .BY

I'm using Hibernate ORM and Spring Data JPA. I have difficulty in creating new Object in SELECT statement, because BY is a reserved word in SQL.

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;

import by.naxa.project.model.Event;
import by.naxa.project.model.Demo;
import by.naxa.project.model.Pair;
import by.naxa.project.model.Response;
import by.naxa.project.model.User;

public interface DemoRepository extends JpaRepository<Demo, Long> {

    /**
     * Find all responses to the given event.
     *
     * @param event Event.
     * @return The list of User-Response tuples.
     */
    @Query("SELECT new by.naxa.project.model.Pair(demo.invitee, demo.response) FROM Demo demo WHERE demo.event = :event")
    List<Pair<User, Response>> findResponsesByEvent(@Param("event") Event event);

}

My classes here are:

Deploy process fails with the following log output:

DEBUG main QueryTranslatorImpl:parse:265 - parse() - HQL: SELECT new by.naxa.project.model.Pair(demo.invitee, demo.response) FROM by.naxa.project.model.Demo demo WHERE demo.event = :event
DEBUG main ErrorCounter:reportWarning:63 - Keyword  'by' is being interpreted as an identifier due to: expecting IDENT, found 'by'
DEBUG main HqlParser:weakKeywords:358 - weakKeywords() : new LT(1) token - ["by",<111> previously: <108>,line=1,col=69,possibleID=true]
DEBUG main QueryTranslatorImpl:showHqlAst:283 - --- HQL AST ---
... 
Caused by: java.lang.ClassCastException: org.hibernate.hql.internal.ast.tree.SqlNode cannot be cast to org.hibernate.hql.internal.ast.tree.FromReferenceNode

I am sure that the only error is that the keyword by is being interpreted as an identifier, because if I rename package to com.naxa.project it is working as intended. Also constructor name must be fully qualified, so I can't write SELECT new Pair(demo.invitee, demo.response) ....

I tried to escape the constructor name with "", '', `` (backticks), () and [].

  • backticks, double quotes:
    org.hibernate.QueryException: unexpected char: '`'
  • single quotes, square brackets, parentheses:
    org.hibernate.hql.internal.ast.QuerySyntaxException: expecting IDENT, found '['

What should I do?

Community
  • 1
  • 1
naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259
  • I'm not sure escaping is possible here. Same might apply for projects from Indonesia :/ – Thomas Jun 17 '15 at 12:43
  • I did a rough search and it seems like this also is a problem for India (.in) and it doesn't seem like there's a way to escape the package names. If you don't get any positive answers you could try and file a RFC or bug with Hibernate. As a workaround, I could think of 2 things: 1. use a different package just for those classes or 2. try and use a custom result transformer along with an altered query that doesn't contain the FQCN (not sure if that would work but it might be worth a try). – Thomas Jun 17 '15 at 12:57
  • @Thomas, I've applied the 1st as a _temporary solution_. And I don't get the 2nd: Is there a way to use `ResultTransformer` along with Spring Data? – naXa stands with Ukraine Jun 17 '15 at 13:09
  • Hmm, I don't know whether you can use a result transformer with Spring Data, that's why I said that I'm not sure solution 2 would work at all. However, if the two don't work together you could still try to not use Spring Data in those cases. Most probably you'll need a tradeoff anyways until a way to escape package names or leave them out of the queries is provided. – Thomas Jun 17 '15 at 13:55

1 Answers1

1

According to Java Package Naming Conventions

In some cases, the internet domain name may not be a valid package name. This can occur if the domain name contains a hyphen or other special character, if the package name begins with a digit or other character that is illegal to use as the beginning of a Java name, or if the package name contains a reserved Java keyword, such as "int". In this event, the suggested convention is to add an underscore.

package by.naxa can be renamed to by_.naxa. And the problem vanishes.

But still I'm looking for the way to escape constructor name in a Hibernate query.

naXa stands with Ukraine
  • 35,493
  • 19
  • 190
  • 259