-->
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.  [ 3 posts ] 
Author Message
 Post subject: Persisting a HashMap<String, Object/String>
PostPosted: Mon Aug 07, 2006 12:16 pm 
Newbie

Joined: Mon Aug 07, 2006 9:13 am
Posts: 2
I've been struggling for a while now to solve the problem of persisting a Hashmap within an object ie.:


private Map<String, String> myMap;
private Map<String, Pet> petMap;


I've found most documentation to be misleading. For example at http://www.hibernate.org/hib_docs/annot ... ollections:

@Entity
public class Software {
@OneToMany(mappedBy="software")
@MapKey(name="codeName")
public Map<String, Version> getVersions() {
return versions;
}
...
}


This is the wrong MapKey and causes errors for me. The only way i got it to work was to use the new MapKey i.e.

import org.hibernate.annotations.MapKey; //IMPORTANT!!
...
@CollectionOfElements
@MapKey(columns={
@Column(name="`key`")
})
private Map<String, String> myMap;



This solves the MySql problem where the key is a reserved word - additionally you can call the key column whatever you wish.

Now, for private Map<String, Pet> petMap; i have:

@OneToMany(cascade = CascadeType.ALL)
@MapKey(columns={
@Column(name="`key`")
})
@JoinColumn(name="petMapOwner_id")
private Map<String, Pet> petMap;


This works fine. What hibernate will do is add a column to the pet table called "key". This will hold the String representation of the key that points to the pet object in question. However, this doesn't quite imitate true hashmap behaviour. For example, suppose you had:

petMap.put("pet2", pet2);
petMap.put("pet3", pet3);

// Hibernate doesn't do this properly - it only stores
// one row Per String and Pet (Object) Pairings

petMap.put("pet3again", pet3);


All the rows in the DB tell you is that pet2 is indexed by the string "pet2" and pet3 is indexed by the string "pet3". But somehow there should be another indication that pet3 is indexed by the string "pet3again" aswell.

"who cares?" i hear you cry. Well... ok its only a problem if you actually want to point to the same object twice with 2 different string hash indexes. And you could just clone the object if you wanted this. But anyway, thought i'd post this and see if

a) people think i'm doing this right in the first place
b) anyone would ever want to index the same object twice by different string indexes
c) if there is sufficient people agreeing with a) and b), then its a bug that needs looking into/process that needs refining.

Thanks

Dan


Top
 Profile  
 
 Post subject:
PostPosted: Sat Aug 12, 2006 5:39 am 
Newbie

Joined: Wed Oct 05, 2005 3:36 am
Posts: 15
I think the problem you have is the relationship between the PetOwner and the Pet is defined to be One-To-Many.

You are saying that you want to have the same Pet appear multiple times.

The Pet would therefore have multiple owners (I realize that all of the owners are the same entity). But from a hibernate standpoint it is still a Many-To-Many relationship (unless you are using bags in which case "special" rules apply **).


** As far as I can tell hibernate makes no effort to remove duplicates when you are using bags (even in some cases where it should), but in all other cases it removes any duplicates inside the same (one-to-many) collection - due to the way it maps the objects to the database, which is why your example doesn't work.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 14, 2006 5:32 am 
Newbie

Joined: Mon Aug 07, 2006 9:13 am
Posts: 2
Thanks for the reply. You're totally right - with the Map<String, Object> defined as ManyToMany, hibernate creates a separate relationship table for contact_pet that can have multiple entries with String Index values pointing to duplicate pet_id's if necessary.

I seemed to have been a little confused over what the relationship of x-To-y is referring. For example the following i believe is correct (this sits in the Contact object):

Code:
@OneToMany(cascade = CascadeType.ALL) 
   @JoinColumn(name="contact_id")
   private List<Pet> pet;


There is "One contact with Many pets in its List" = OneToMany.

But then from this error i've made at the start of the thread, the following is incorrect:

Code:
@OneToMany(cascade = CascadeType.ALL) 
   @MapKey(columns={
          @Column(name="petkey")
      })
   @JoinColumn(name="petMapOwner_id")
   private Map<String, Pet> petMap;


Even though there is "One contact with Many entries in the Map".

Is then the relatioship "ManyToMany" referring to the Many String indexes to Many Pet objects? It just doesn't quite make sense to me what the x-To-y relationship is referring to. I imagine my mistake is to think of the relationship on a single object scale, rather than system wide - but then wouldn't that just make every relationship ManyToMany?!? (unless the parent was a singleton!). Hopefully i'll realise why i'm picturing it wrong in due time, but at the moment it feels inconsistent.


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