-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: JPA query on a map-key that is an enum
PostPosted: Thu Jun 12, 2008 1:32 pm 
Newbie

Joined: Thu Jun 12, 2008 12:47 pm
Posts: 3
I have an Entity-class (mapped using JPA annotations and some hibernate-annotations, mostly just @CollectionOfElements) that has a persistent java.util.Map field, using a (java 5) enum as the key and a self-defined class as the value (see below). Persisting this in the database works great, but i have the problem that trying to build a query on the map-values creates an exception. The query looks like this:
Code:
EntityManager entityManager; //...
      
Query query = entityManager.createQuery("select user from User user where user.profile[:nameEnum] = :name");
query.setParameter("nameEnum", ProfileEntryKey.NAME);
query.setParameter("name", "Some Name");
      
List<User> users = query.getResultList();


The the last line throws an exception with the strange reason "Invalid character string format for type INTEGER" whose stacktrace is reproduced below.

Now my question is: Is this a problem with my mappings? With my query syntax? Or could it be a problem specific to the derby database and its dialect?

Regards,
David


Hibernate versions:
Hibernate 3.2.6-GA, Hibernate Annotations 3.3.1.GA, Hibernate EntityManager 3.3.2.GA

Mapped Classes:
User.java:
Code:
@Entity
public class User {
   public enum ProfileEntryKey {
      NAME, // ...
   }

   // ...

   @CollectionOfElements(fetch = LAZY)
   public Map<ProfileEntryKey, ProfileEntry> getProfile() {
      return profile;
   }
}


ProfileEntry.java:
Code:
@Embeddable
public class ProfileEntry {
   
   // ...
   
   @Basic(optional=false)
   public String getValue() {
      return value;
   }
   
   @Enumerated(value=EnumType.ORDINAL)
   @Basic(optional=false)
   public PrivacyLevel getLevel() {
      return level;
   }
   
   // ...
}



Full stack trace of any exception that occurs:
Code:
[#|2008-06-12T19:19:54.416+0200|SEVERE|
sun-appserver9.1|javax.enterprise.system.container.web|
_ThreadID=20;_ThreadName=httpSSLWorkerThread-8080-1;
_RequestID=4ba1fce4-bf67-4382-9f68-d15c6493f6c9;|
StandardWrapperValve[TestServlet]: PWC1406: Servlet.service() for servlet TestServlet threw exception
javax.persistence.PersistenceException: org.hibernate.exception.DataException: could not execute query
   at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:637)
   at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:74)
   at de.myv.platform.user.TestServlet.testSearch(TestServlet.java:61)
   at de.myv.platform.user.TestServlet.doGet(TestServlet.java:137)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:718)
   at javax.servlet.http.HttpServlet.service(HttpServlet.java:831)
   at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:411)
   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:290)
   at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:271)
   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:202)
   at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
   at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
   at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94)
   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:206)
   at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
   at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
   at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
   at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:150)
   at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:632)
   at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:577)
   at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:571)
   at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1080)
   at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:272)
   at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:637)
   at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:568)
   at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:813)
   at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341)
   at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263)
   at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214)
   at com.sun.enterprise.web.portunif.PortUnificationPipeline$PUTask.doTask(PortUnificationPipeline.java:380)
   at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:265)
   at com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run(SSLWorkerThread.java:106)
Caused by: org.hibernate.exception.DataException: could not execute query
   at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:77)
   at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
   at org.hibernate.loader.Loader.doList(Loader.java:2216)
   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:65)
   ... 31 more
Caused by: java.sql.SQLException: Invalid character string format for type INTEGER.
   at org.apache.derby.client.am.SQLExceptionFactory.getSQLException(Unknown Source)
   at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
   at org.apache.derby.client.am.PreparedStatement.executeQuery(Unknown Source)
   at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
   at org.hibernate.loader.Loader.getResultSet(Loader.java:1787)
   at org.hibernate.loader.Loader.doQuery(Loader.java:674)
   at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
   at org.hibernate.loader.Loader.doList(Loader.java:2213)
   ... 39 more
Caused by: org.apache.derby.client.am.SqlException: Invalid character string format for type INTEGER.
   at org.apache.derby.client.am.Statement.completeSqlca(Unknown Source)
   at org.apache.derby.client.am.Statement.completeOpenQuery(Unknown Source)
   at org.apache.derby.client.net.NetStatementReply.parseOpenQueryFailure(Unknown Source)
   at org.apache.derby.client.net.NetStatementReply.parseOPNQRYreply(Unknown Source)
   at org.apache.derby.client.net.NetStatementReply.readOpenQuery(Unknown Source)
   at org.apache.derby.client.net.StatementReply.readOpenQuery(Unknown Source)
   at org.apache.derby.client.net.NetStatement.readOpenQuery_(Unknown Source)
   at org.apache.derby.client.am.Statement.readOpenQuery(Unknown Source)
   at org.apache.derby.client.am.PreparedStatement.flowExecute(Unknown Source)
   at org.apache.derby.client.am.PreparedStatement.executeQueryX(Unknown Source)
   ... 45 more
|#]


Name and version of the database you are using:
Apache Derby Network Server 10.2.2.1 (aka. the JavaDB in Glassfish v2ur1)


Top
 Profile  
 
 Post subject: Re: JPA query on a map-key that is an enum
PostPosted: Fri Jun 13, 2008 10:06 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Hi David,

have you tried:

[quote="DavidKlotz"]
Code:
EntityManager entityManager; //...
      
Query query = entityManager.createQuery("select user from User user where user.profile[:nameEnum] = :name");
query.setParameter("nameEnum", ProfileEntryKey.NAME.ordinal());
query.setParameter("name", "Some Name");
      
List<User> users = query.getResultList();


That's maybe not intuitive, but could work since the enum type gets persisted as simple int.

--Hardy


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 13, 2008 10:22 am 
Newbie

Joined: Thu Jun 12, 2008 12:47 pm
Posts: 3
Changing the query to use the ordinal value changes the SQLException to "An attempt was made to put a data value of type 'int' into a data value of type 'VARCHAR () FOR BIT DATA'.".

And its right in that, the map key does get persisted as a "VARCHAR FOR BIT DATA" (whatever that is, maybe some kind of CLOB/BLOB). I would very much like it to be persisted as the ordinal or string representation of the enum instead.

If i have a simple property of the enum type i can use @Enumerated to choose between the ordinal and the string representation, but using the enum as a map key of the @CollectionOfElements gets persisted as this "VARCHAR FOR..." type, which i think is kind of strange.

Is there some way to change that behavior?

Thanks,
David


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 17, 2008 11:22 am 
Newbie

Joined: Thu Jun 12, 2008 12:47 pm
Posts: 3
No other ideas? Is this (the fact that the enum map key gets persisted neither as a string nor as the ordinal) a bug that i should report? Or is it intended?

Regardless of how it is persisted, there must be some way to do a query with it, shouldn't it?

-David


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.