1 Reply Latest reply on Feb 17, 2011 8:38 AM by Serkan Eskici

    List with "Switched Restrictions", using enum array, gives ClassCastException

    Ian Darwin Newbie
      Building a simplified Bugzilla-like interface into a SeamGen project. Seam 2.1.2, JBossAS 4.2.2.

      BugStatus is a Java5 Enum of 5 states, 3 of which are considered
      "open" and two "closed". To avoid denormalizing the data model,
      we don't have a separate open/closed boolean, but the enum has an
      additional "openValues()" method, patterned on the Enum values()
      method, that returns BugStatus[]. There is a @Factory for this
      that exports it under the name 'bugOpenStatuses'.

      BugStatus is used with s:convertEnum and it all works, except for
      one thing in the List page.

      Section 10.4.5, Page 426, of Seam in Action contains this example of placing a dynamic restriction on the results:

        <value>c IN(#{not empty roundCriteria.courses ?
           roundCriteria.courses : null})</value>

      Patterning after that I had:

        <value>b.bugStatus IN(#{bugListCriteria.includeClosed ?
             null : bugOpenStatuses })</value>

      (The current version has this in a Java-based List component instead of XML but the same restriction is there and the failure mode is the same).

      SiA also notes (same page) that "An explicit check for an empty collection must be performed or an empty IN() clause is generated, resulting in a SQL error." However in this case the 'bugOpenStatuses' cannot be null as it is coming from a static array; I'm using the boolean to determine whether the user requested the full or partial display.

      Anyway, the result is: if includeClosed is true, this value restriction returns null and is ignored, and the page displays the complete list. If includeClosed is false, the array gets selected, and correct SQL is generated:

      22:15:40,467 INFO  [STDOUT] Hibernate: select bug0_.id as id3_, bug0_.URL as URL3_, bug0_.description as descript3_3_, bug0_.note as note3_, bug0_.title as title3_, bug0_.submittor_id as submittor11_3_, bug0_.created as created3_, bug0_.bugStatus as bugStatus3_, bug0_.bugComponent as bugCompo8_3_, bug0_.bugType as bugType3_, bug0_.approved as approved3_ from Bug bug0_ where (bug0_.bugStatus in (?)) and bug0_.approved=? order by bug0_.created desc, bug0_.bugComponent asc

      But then it crashes with a ClassCastException saying that it's not expecting the array of enums but wants a single enum. What I can't tell is: is this my bug, or a bug in Seam, or a bug in Hibernate? How to track this down further?

      java.lang.ClassCastException: [Lbugs.BugStatus; cannot be cast to java.lang.Enum
              at org.hibernate.type.EnumType.nullSafeSet(EnumType.java:125)
              at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:156)
              at org.hibernate.param.NamedParameterSpecification.bind(NamedParameterSpecification.java:38)
              at org.hibernate.loader.hql.QueryLoader.bindParameterValues(QueryLoader.java:491)
              at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1563)
              at org.hibernate.loader.Loader.doQuery(Loader.java:673)
              at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
              at org.hibernate.loader.Loader.doList(Loader.java:2220)
              at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
              at org.hibernate.loader.Loader.list(Loader.java:2099)
              at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:378)
              at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)
              at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
              at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)
              at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
              at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:64)
              at org.jboss.seam.framework.EntityQuery.initResultList(EntityQuery.java:80)
              at org.jboss.seam.framework.EntityQuery.getResultList(EntityQuery.java:71)
              at sun.reflect.GeneratedMethodAccessor212.invoke(Unknown Source)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
              at java.lang.reflect.Method.invoke(Method.java:617)
              at javax.el.BeanELResolver.getValue(BeanELResolver.java:62)
              at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:53)
              at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:64)
              at org.jboss.el.parser.AstPropertySuffix.getValue(AstPropertySuffix.java:53)
              at org.jboss.el.parser.AstValue.getValue(AstValue.java:67)
              at org.jboss.el.parser.AstEmpty.getValue(AstEmpty.java:29)
              at org.jboss.el.parser.AstChoice.getValue(AstChoice.java:27)
              at org.jboss.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
              at com.sun.facelets.el.ELText$ELTextVariable.writeText(ELText.java:184)
              at com.sun.facelets.el.ELText$ELTextComposite.writeText(ELText.java:108)
              at com.sun.facelets.compiler.TextInstruction.write(TextInstruction.java:45)