-->
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.  [ 2 posts ] 
Author Message
 Post subject: How to fetch a <map> in Hibernate
PostPosted: Tue Feb 18, 2014 7:03 pm 
Newbie

Joined: Tue Feb 18, 2014 6:51 pm
Posts: 2
Hi all,

I'm simply trying to fetch the contents of a HashMap persisted in Hibernate, but I'm having some trouble finding the correct way to do it.

I've detailed my problem on StackOverflow: http://stackoverflow.com/questions/21703851/how-to-fetch-a-map-in-hibernate. I've also uploaded an example on GitHub: https://github.com/seanhodges/HibernateSandbox/tree/master

To summarise; I have an entity map collection that looks like this:

Code:
        <map name="documentbundles" table="document_bundles" lazy="false">
            <key column="id"/>
            <index-many-to-many column="pkgitemid" class="database.PkgItem"/>
            <many-to-many column="child" class="database.Document" />
        </map>


When I try to perform a lookup on the map collection that is returned, the keys are all proxy objects, so none of my

I've tried various queries, but the one in my GitHub project attempts to do this:

Code:
List results = hibernateTemplate.find("from database.Document d where d.name = 'doc1'");
Document result = (Document)results.get(0);
Document child result.getDocumentbundles().get(myPkgItem);


The result I get is child is always null, since the proxy in the HashMap does not match my original key object.

Can anyone help?


Top
 Profile  
 
 Post subject: Re: How to fetch a <map> in Hibernate
PostPosted: Wed Feb 19, 2014 1:43 pm 
Newbie

Joined: Tue Feb 18, 2014 6:51 pm
Posts: 2
With some help on StackOverflow I think I've got to grips with how maps work. I'm posting my current conclusion here for completeness and in case someone in the community has some input.

In summary, you can't fetch a PersistedMap with a Hibernate query and immediately start using it like a typical Java hash map. The keys are always proxies; eager fetching / joining only fetches the map values, not the keys.

This means any code that deals with the hash map needs to be wrapped in a Hibernate transaction, which caused me some architectural problems as my data and service layers are separate.

I worked around this by iterating the hash map within a transaction (as described here: http://stackoverflow.com/a/21867936/43662) and replacing the keys with the ones originally passed in. I kept performance up by batching up the keys I want to fetch and retrieving them in one go:

Code:
// Build a list of keys we want to fetch in one go
final List<PkgItem> pkgItems = Arrays.asList(pkgItem1, pkgItem2, ...);

Map<PkgItem, Document> bundles = transactionTemplate.execute(new TransactionCallback< Map<PkgItem, Document> >() {
    @Override
    public Map<PkgItem, Document> doInTransaction(TransactionStatus transactionStatus) {
        if (doc1.getId() == null) return null;

        // Merge the parent document into this transaction
        Document container = hibernateTemplate.merge(doc1);

        // Copy the original package items into the key set
        Map<PkgItem, Document> out = new HashMap<PkgItem, Document>();
        for (PkgItem dbKey : container.getDocumentbundles().keySet()) {
            int keyIndex = pkgItems.indexOf(dbKey);
            if (keyIndex > -1) out.put(pkgItems.get(keyIndex), container.getDocumentbundles().get(dbKey));
        }
        return out;
    }
});

// Now we can perform a standard lookup
assertEquals("doc2", result.get(pkgItem1).getName());


I can now use the map without Hibernate in the resulting code, with only a minimal performance hit. I've also updated the test in my example GitHub project to demonstrate how this can work.


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