-->
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.  [ 5 posts ] 
Author Message
 Post subject: How to map a <map> key=string value=array of string
PostPosted: Tue Jan 15, 2008 2:46 pm 
Newbie

Joined: Tue Jan 15, 2008 2:11 pm
Posts: 5
Hi everyone,
I am having troubles with mapping a map containing an array as it's value type (a simple array of string).

The only piece of information relating to my problem I could find was the following: http://osdir.com/ml/java.french.general ... 00025.html
It is in french but the person answering mainly explains that his understanding of the DTD makes him think that it's impossible to persist a map of map.

Is it true or is there a piece of information I missed in the documentation?

I don't know what to put in place of the <element> tag to be able to persist that array of string.
Code:
<map name="mMap">
  <key column="MyMapId"/>
  <map-key type="string"/>
  <element type="string"/>
</map>


Hibernate version:
3.2.2
Hibernate configuration:
<!-- Auto commit transactions to the DB -->
<property name="connection.autocommit">false</property>

<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>

<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>

<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">auto</property>

Mapping documents:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<!-- TODO find a better solution for lazy loading policy -->
<hibernate-mapping package="com.tests"
default-access="field"
default-cascade="save-update"
default-lazy="false">

<class name="TestMap$MyMap" table="mymap">
<id type="long">
<generator class="increment"/>
</id>
<map name="mMap">
<key column="MyMapId"/>
<map-key type="string"/>
<element type="string"/> <!-- there I would like to put something like type=string-array or use an <array> instead of the <element> tag-->
</map>
</class>

</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():

Full stack trace of any exception that occurs:
Hibernate: select max(id) from mymap
Hibernate: insert into mymap (id) values (?)
Hibernate: insert into mMap (MyMapId, idx, elt) values (?, ?, ?)
java.lang.ClassCastException
at org.hibernate.type.StringType.toString(StringType.java:44)
at org.hibernate.type.NullableType.nullSafeToString(NullableType.java:93)
at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:140)
at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:107)
at org.hibernate.persister.collection.AbstractCollectionPersister.writeElement(AbstractCollectionPersister.java:755)
at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1143)
at org.hibernate.action.CollectionRecreateAction.execute(CollectionRecreateAction.java:26)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:143)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.tests.TestMap.testMap(TestMap.java:62)
at com.tests.TestMap.main(TestMap.java:47)


The class cast exception obviously happens because the java type is String[] and mapping file describes says it's a string since I don't know how to specify it should be an array.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 17, 2008 4:03 am 
Newbie

Joined: Tue Jan 15, 2008 2:11 pm
Posts: 5
No idea anyone ? No pointer, any indication ?

All I know is that the <map> tag has an inner <element> tag to indicate describe the objects stored in the map.

That <element> can also be <composit-element>, <one-to-many> or <many-to-many>.

I could achieve the persistence of the map with the composit-element tag but that forces me to write an intermediary class 'MyMapValues' containing the values in the form of the String array.

However I wouldn't like to have to write intermediary classes for all the maps of my code containing different collections as values.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 21, 2008 9:02 am 
Newbie

Joined: Thu Nov 29, 2007 12:39 pm
Posts: 4
I had the same problem recently, and what I did was creating a StringArray wrapper class, and using that as the element. For what I understood (I may be wrong though) there is no other way.

<element> requires that the element be a basic type (which an array is not).

<one-to-many> or <many-to-many> require that the element be an entity (a class). This is what I used, having the StringArray as an element.

<composite-element> clearly states in the documention that it cannot have collection properties, so we cannot have a <composite-element> with and <array> collection. You can map an array as a property though:
<composite-element class="com.foo.StringArray" table="FOO_STRINGS">
<property name="strings"></property>
<composite-element>

and it will serialize the array into one column, but you'll still need a StringArray wrapper class, and because you are serializing the array in a column, it may be limited in size. So because of this I didn't use this solution.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 22, 2008 4:40 am 
Newbie

Joined: Tue Jan 15, 2008 2:11 pm
Posts: 5
Thank you for your answer.

That's what I was afraid of, however this seems to me as non negligible constraint.
Having to wrap all the map entries to StringArrays, IntArrays ... may potentially represent a lot of work depending on the original architecture.

Hopefully I don't have too much of them for now so I can do it.
I was just hoping there would be a standard generic solution for that problem.

Thank you again.


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 13, 2008 5:11 pm 
Beginner
Beginner

Joined: Mon Nov 19, 2007 4:40 pm
Posts: 46
Does anyone from hibernate care to respond to this? I am also suffering from this problem... I need to map a Set of values.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 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.