History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: HHH-362
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Minor Minor
Assignee: Unassigned
Reporter: Robert Watkins
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Hibernate3

HSQL doesn't support character constants properly.

Created: 18/Apr/05 02:20 AM   Updated: 19/Apr/05 01:02 AM
Component/s: core
Affects Version/s: 3.0 final
Fix Version/s: 3.0.2

Time Tracking:
Not Specified

Environment: Hibernate 3.0, Oracle 10


 Description  « Hide
In migration from Hibernate 2.1.6 to Hibernate 3.0, a named query stopped working. It referenced a string constant. The reported error was a syntax error.

Example HSQL:
from Foo foo where foo.status = foo.bar.Foo.STATUS_APPROVED

[ Foo.STATUS_APPROVED = new Character('A') ]

Error:
18/04/2005 17:16:38 org.hibernate.impl.SessionFactoryImpl <init> SEVERE: Error in named query: Booking.getCheckinsForDay
org.hibernate.hql.ast.QuerySyntaxError: unexpected AST node: 'A' [
            from Foo foo where foo.status = foo.bar.Foo.STATUS_APPROVED
        ]
at org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:63)
at org.hibernate.hql.ast.QueryTranslatorImpl.generate(QueryTranslatorImpl.java:180)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:146)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:83)
at org.hibernate.impl.SessionFactoryImpl.getQuery(SessionFactoryImpl.java:414)
at org.hibernate.impl.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:375)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:278)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1054)
at foo.bar.HibernateConfigTest.testCreateSessionFactory(HibernateConfigTest.java:152)
...


The workaround (once the error message is diagnosed) seems to be to place the constant in quotes. However, I'm yet to be able to test it to see if this does the job, or if it merely makes it look for the constant name instead.

Possibly-good HSQL: from Foo foo where foo.status = 'foo.bar.Foo.STATUS_APPROVED'


This was not a problem under Hibernate 2.1.6

 All   Comments   Work Log   Change History   FishEye      Sort Order: Ascending order - Click to sort in descending order
Joshua Davis - 18/Apr/05 06:42 AM
The HQL translator should interpret that as a constant, without the quotes (unless somebody broke something ;-> ). How is that constant defined? Is that the part in square brackets?

Robert Watkins - 18/Apr/05 08:28 AM
Yes, the bit in the brackets is the definition of the constant.

As far as I can tell, it _is_ interpreting it as a comment. Hence the error about "Unexpected AST Node: 'A'". Perhaps how it is being interpreted is the problem?

Joshua Davis - 18/Apr/05 10:07 AM
No, it's not interpreting it as a comment. What I meant was, in your example HQL:

from Foo foo where foo.status = foo.bar.Foo.STATUS_APPROVED

[ Foo.STATUS_APPROVED = new Character('A') ]

What is the second line with the square brackets around it? Is that how Foo.STATUS_APPROVED is declared in the JAVA code? The reason I ask is that the new HQL translator is attempting to resolve foo.bar.Foo.STATUS_APPROVED using the context class loader. The last symbol in the path is STATUS_APPROVED, and that is expected to be a field in foo.bar.Foo with static scope and public visibility. Is that the case here? If not, the new HQL translator will continue on trying to bind foo.bar.Foo.STATUS_APPROVED to something.


Steve Ebersole - 18/Apr/05 10:40 AM
It finds/resolves the static reference; note the "unexpected AST node : 'A'", as is the value of that static reference.

Robert, we'd need to see the AST for this error. Enable debug on the org.hibernate.hql.AST logger, and paste the resulting tree here.

Steve Ebersole - 18/Apr/05 10:41 AM
BTW, its HQL; HSQL is a database :)

Gavin King - 18/Apr/05 03:28 PM
This should now be fixed in CVS. Please test.

Robert Watkins - 18/Apr/05 07:15 PM
It now supports Characters fine. However, it no longer supports Strings (and this time I mean Strings! ;)

Here's the HQL:
------
select contact from SupplierWotifContact contact where contact.country.isoCountryCode = com.wotif.jaguar.domain.Country.AUSTRALIA_ISO_CODE and contact.region is null
------

[com.wotif.jaguar.domain.County.AUSTRALIA_ISO_CODE = "AU"]

And here's the AST tree, as requested:
19/04/2005 10:01:59 org.hibernate.hql.ast.QueryTranslatorImpl analyze FINE: --- SQL AST ---
 \-[SELECT] QueryNode: 'SELECT' querySpaces (COUNTRY,SUPPLIER_WOTIF_CONTACT)
    +-[SELECT_CLAUSE] SelectClause: '{select clause}'
    | +-[ALIAS_REF] IdentNode: 'supplierwo0_.ID as ID' {alias=contact, className=com.wotif.jaguar.domain.SupplierWotifContact, tableAlias=supplierwo0_}
    | \-[SQL_TOKEN] SqlFragment: 'supplierwo0_.COUNTRY as COUNTRY37_, supplierwo0_.REGION as REGION37_, supplierwo0_.STAFF_MEMBER as STAFF4_37_, supplierwo0_.DESCRIPTION as DESCRIPT5_37_'
    +-[FROM] FromClause: 'from' FromClause{level=1, fromElementCounter=2, fromElements=2, fromElementByClassAlias=[contact], fromElementByTableAlias=[country1_, supplierwo0_], fromElementsByPath=[contact.country], collectionJoinFromElementsByPath=[], impliedElements=[]}
    | +-[FROM_FRAGMENT] FromElement: 'SUPPLIER_WOTIF_CONTACT supplierwo0_' FromElement{explicit,not a collection join,not a fetch join,fetch non-lazy properties,classAlias=contact,role=null,tableName=SUPPLIER_WOTIF_CONTACT,tableAlias=supplierwo0_,colums={,className=com.wotif.jaguar.domain.SupplierWotifContact}}
    | \-[FROM_FRAGMENT] ImpliedFromElement: 'COUNTRY country1_' ImpliedFromElement{implied,not a collection join,not a fetch join,fetch non-lazy properties,classAlias=null,role=null,tableName=COUNTRY,tableAlias=country1_,colums={supplierwo0_.COUNTRY ,className=com.wotif.jaguar.domain.Country}}
    \-[WHERE] SqlNode: 'where'
       +-[AND] SqlNode: 'and'
       | +-[EQ] SqlNode: '='
       | | +-[DOT] DotNode: 'country1_.ISO_CountryCode' {propertyName=isoCountryCode,dereferenceType=4,propertyPath=isoCountryCode,path=contact.country.isoCountryCode,tableAlias=country1_,className=com.wotif.jaguar.domain.Country,classAlias=null}
       | | | +-[DOT] DotNode: 'supplierwo0_.COUNTRY' {propertyName=country,dereferenceType=1,propertyPath=country,path=contact.country,tableAlias=country1_,className=com.wotif.jaguar.domain.Country,classAlias=null}
       | | | | +-[ALIAS_REF] IdentNode: 'supplierwo0_.ID' {alias=contact, className=com.wotif.jaguar.domain.SupplierWotifContact, tableAlias=supplierwo0_}
       | | | | \-[IDENT] IdentNode: 'country' {originalText=country}
       | | | \-[IDENT] IdentNode: 'isoCountryCode' {originalText=isoCountryCode}
       | | \-[CONSTANT] DotNode: ''AU'' {propertyName=AUSTRALIA_ISO_CODE,dereferenceType=6,propertyPath=AUSTRALIA_ISO_CODE,path=com.wotif.jaguar.domain.Country.AUSTRALIA_ISO_CODE,no from element}
       | \-[IS_NULL] SqlNode: 'is null'
       | \-[DOT] DotNode: 'supplierwo0_.REGION' {propertyName=region,dereferenceType=ROOT_LEVEL,propertyPath=region,path=contact.region,tableAlias=supplierwo0_,className=com.wotif.jaguar.domain.SupplierWotifContact,classAlias=contact}
       | +-[ALIAS_REF] IdentNode: 'supplierwo0_.ID' {alias=contact, className=com.wotif.jaguar.domain.SupplierWotifContact, tableAlias=supplierwo0_}
       | \-[IDENT] IdentNode: 'region' {originalText=region}
       \-[THETA_JOINS] SqlNode: '{theta joins}'
          \-[SQL_TOKEN] SqlFragment: 'supplierwo0_.COUNTRY=country1_.CountryCode'

19/04/2005 10:01:59 org.hibernate.hql.ast.ErrorCounter reportError SEVERE: *** ERROR: <AST>:0:0: unexpected AST node: 'AU'

Gavin King - 18/Apr/05 11:07 PM
Actually, I briefly had a bug, which I fixed, possibly you happened to update from CVS while the bug was still there. Re-update and retry. Note that you MUST run "ant antlr".

Robert Watkins - 19/Apr/05 01:02 AM
I can confirm it works for me now. :)