glassfish
  1. glassfish
  2. GLASSFISH-269

@Enumerated does not work well with ejb-ql

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 9.0pe
    • Fix Version/s: 9.1pe_dev
    • Component/s: entity-persistence
    • Labels:
      None
    • Environment:

      Operating System: All
      Platform: Linux

    • Issuezilla Id:
      269

      Description

      I ran into problems using @Enumerated(ORDINAL) or @Enumerated(STRING) in
      combination with ejb-ql.

      The enum information is stored like expected in the database,
      but when querying the database the glassfish error log tells me that there is no
      conversion defined.

      I'll attach an ant project so that you can reproduce the bug

        Issue Links

          Activity

          Hide
          lucduponcheel added a comment -

          Created an attachment (id=79)
          zipped-up ant project

          Show
          lucduponcheel added a comment - Created an attachment (id=79) zipped-up ant project
          Hide
          tware added a comment -

          entity-persistence bugs should be initially assigned to tware

          Show
          tware added a comment - entity-persistence bugs should be initially assigned to tware
          Hide
          marina vatkina added a comment -

          Fixed subcomponent and reassigned to Jielin

          Show
          marina vatkina added a comment - Fixed subcomponent and reassigned to Jielin
          Hide
          jielin added a comment -

          try to reproduce the bug

          Show
          jielin added a comment - try to reproduce the bug
          Hide
          jielin added a comment -

          I investigate the attached application. The problem is that user can not compare
          enum with integer in query string:

          Query q = em.createQuery("select object(e) from SOMEENTITY as e where e.value = 0");

          Since e.value is enum type, the correct way doing that is:

          Query q = em.createQuery("select object(e) from SOMEENTITY as e where e.value =
          :value");
          q.setParameter("value", SomeEnum.OK);

          This user error should be catched by EJBQL compiler when validate the input token.

          Change to p4 for ejbql validation to give better error message.

          Show
          jielin added a comment - I investigate the attached application. The problem is that user can not compare enum with integer in query string: Query q = em.createQuery("select object(e) from SOMEENTITY as e where e.value = 0"); Since e.value is enum type, the correct way doing that is: Query q = em.createQuery("select object(e) from SOMEENTITY as e where e.value = :value"); q.setParameter("value", SomeEnum.OK); This user error should be catched by EJBQL compiler when validate the input token. Change to p4 for ejbql validation to give better error message.
          Hide
          marina vatkina added a comment -

          Need an improved message as this error might happen with many users.

          Show
          marina vatkina added a comment - Need an improved message as this error might happen with many users.
          Hide
          jielin added a comment -

          checkin code.

          Show
          jielin added a comment - checkin code.
          Hide
          smcgowan added a comment -

          This fix seems to have caused a regression with the following EJB QL query.
          Reopening for reevaluation.

          Query q = getEntityManager().createQuery(
          "SELECT dt FROM DataTypes dt WHERE dt.enumData =
          tests.types.common.Grade.A");

          result = (DataTypes) q.getSingleResult();
          [#|2006-10-24T10:03:10.475-0400|WARNING|sun-appserver-pe9.1|javax.enterprise.system.stream.err|_ThreadID=133;_ThreadName=p:

          >> thread-pool-1; w: 27;_RequestID=ac7ab8b6-2903-42ac-8127-5125deeb82fd;|
          >> java.lang.IllegalArgumentException: An exception occured while creating
          >> a query in EntityManager
          >> at
          >>
          oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerImpl.createQuery(EntityManagerImpl.java:180)
          >> at
          >> tests.types.field.Client.fieldTypeTest15(Client.java:845)
          >> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          >> at
          >> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
          >> at
          >>
          >> Caused by: Exception [TOPLINK-8035] (Oracle TopLink Essentials - 9.1
          >> (Build b22)): oracle.toplink.essentials.exceptions.EJBQLException
          >> Exception Description: Invalid enum equal expression, cannot compare
          >> enum value of type tests.types.common.Grade
          >> with a non enum value of type null.
          >> at
          >>
          oracle.toplink.essentials.exceptions.EJBQLException.invalidEnumEqualExpression(EJBQLException.java:445)
          >> at
          >>
          oracle.toplink.essentials.internal.parsing.EqualsNode.validate(EqualsNode.java:55)
          >> at
          >> oracle.toplink.essentials.internal.parsing.WhereNode.validate(WhereNode.java:43)
          >> at
          >> oracle.toplink.essentials.internal.parsing.ParseTree.validate(ParseTree.java:215)
          >> at
          >> oracle.toplink.essentials.internal.parsing.ParseTree.validate(ParseTree.java:192)
          >> at
          >> oracle.toplink.essentials.internal.parsing.ParseTree.validate(ParseTree.java:182)
          >> at
          >>
          oracle.toplink.essentials.internal.parsing.EJBQLParseTree.populateReadQueryInternal(EJBQLParseTree.java:119)
          >> at
          >>
          oracle.toplink.essentials.internal.parsing.EJBQLParseTree.populateQuery(EJBQLParseTree.java:93)
          >> at
          >>
          oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:215)
          >> at
          >>
          oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:174)
          >> at
          >>
          oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:138)
          >> at
          >>
          oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.<init>(EJBQueryImpl.java:99)
          >> at
          >>
          oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.<init>(EJBQueryImpl.java:84)
          >> at
          >>
          oracle.toplink.essentials.internal.ejb.cmp3.EJBQueryImpl.<init>(EJBQueryImpl.java:71)
          >> at
          >>
          oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerImpl.createQuery(EntityManagerImpl.java:175)

          DataTypes.java:
          @Column(name = "ENUMSDATA")
          @Enumerated(EnumType.STRING)
          protected Grade enumData;

          Show
          smcgowan added a comment - This fix seems to have caused a regression with the following EJB QL query. Reopening for reevaluation. Query q = getEntityManager().createQuery( "SELECT dt FROM DataTypes dt WHERE dt.enumData = tests.types.common.Grade.A"); result = (DataTypes) q.getSingleResult(); [#|2006-10-24T10:03:10.475-0400|WARNING|sun-appserver-pe9.1|javax.enterprise.system.stream.err|_ThreadID=133;_ThreadName=p: >> thread-pool-1; w: 27;_RequestID=ac7ab8b6-2903-42ac-8127-5125deeb82fd;| >> java.lang.IllegalArgumentException: An exception occured while creating >> a query in EntityManager >> at >> oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerImpl.createQuery(EntityManagerImpl.java:180) >> at >> tests.types.field.Client.fieldTypeTest15(Client.java:845) >> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >> at >> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) >> at >> >> Caused by: Exception [TOPLINK-8035] (Oracle TopLink Essentials - 9.1 >> (Build b22)): oracle.toplink.essentials.exceptions.EJBQLException >> Exception Description: Invalid enum equal expression, cannot compare >> enum value of type tests.types.common.Grade >> with a non enum value of type null. >> at >> oracle.toplink.essentials.exceptions.EJBQLException.invalidEnumEqualExpression(EJBQLException.java:445) >> at >> oracle.toplink.essentials.internal.parsing.EqualsNode.validate(EqualsNode.java:55) >> at >> oracle.toplink.essentials.internal.parsing.WhereNode.validate(WhereNode.java:43) >> at >> oracle.toplink.essentials.internal.parsing.ParseTree.validate(ParseTree.java:215) >> at >> oracle.toplink.essentials.internal.parsing.ParseTree.validate(ParseTree.java:192) >> at >> oracle.toplink.essentials.internal.parsing.ParseTree.validate(ParseTree.java:182) >> at >> oracle.toplink.essentials.internal.parsing.EJBQLParseTree.populateReadQueryInternal(EJBQLParseTree.java:119) >> at >> oracle.toplink.essentials.internal.parsing.EJBQLParseTree.populateQuery(EJBQLParseTree.java:93) >> at >> oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:215) >> at >> oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:174) >> at >> oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:138) >> at >> oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.<init>(EJBQueryImpl.java:99) >> at >> oracle.toplink.essentials.internal.ejb.cmp3.base.EJBQueryImpl.<init>(EJBQueryImpl.java:84) >> at >> oracle.toplink.essentials.internal.ejb.cmp3.EJBQueryImpl.<init>(EJBQueryImpl.java:71) >> at >> oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerImpl.createQuery(EntityManagerImpl.java:175) DataTypes.java: @Column(name = "ENUMSDATA") @Enumerated(EnumType.STRING) protected Grade enumData;
          Hide
          jielin added a comment -

          The error is thrown by class EqualsNode when analyzing the equals expression
          dt.enumData = com.sun.ts.tests.ejb30.persistence.types.common.Grade.A
          As part of the previous fix added some code to the EqualsNode checking the types
          of the left and right side of an equals. Unfortunately, the compiler does not
          correctly calculate the type of the enum constant Grade.A; it calculates the
          type as null. So the code added throws the exception, because the types dot not
          match. Please note, the bug is not in the code added. The fix is simple: we need
          to change the type calculation in class DotNode and set the type of the dot node
          at the end of method validate.

          Show
          jielin added a comment - The error is thrown by class EqualsNode when analyzing the equals expression dt.enumData = com.sun.ts.tests.ejb30.persistence.types.common.Grade.A As part of the previous fix added some code to the EqualsNode checking the types of the left and right side of an equals. Unfortunately, the compiler does not correctly calculate the type of the enum constant Grade.A; it calculates the type as null. So the code added throws the exception, because the types dot not match. Please note, the bug is not in the code added. The fix is simple: we need to change the type calculation in class DotNode and set the type of the dot node at the end of method validate.

            People

            • Assignee:
              jielin
              Reporter:
              lucduponcheel
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: