[hibernate-dev] Implement UserCollectionType for non-Collection types such as Guava's Multimap

Jan-Willem Gmelig Meyling jan-willem at youngmediaexperts.nl
Mon May 1 05:18:41 EDT 2017


Hi Steve,

Thanks for your response to my questions! Good to see that my intuition was right that this was currently not so trivial if even possible to do. I’ll read up on the 6.0 code base as I am definitely willing to join the ride for Hibernate 6. What is the current status of the Hibernate 6.0 type redesign?

What I was wondering though is whether the support of JDBC array types would pave the way for array-based subselect fetching of to-many relations. I am thinking of for example Postgresql’s array_agg function. In some of our more complex domain entities I’ve been struggling with eagerly fetching multiple to-many relations or deeper to-many relations without getting a relatively large cross product. I currently do use subselect fetching for this but I think having the ability to inline rows (perhaps even recursively) in arrays would decrease query time, number of queries and result set size significantly. 

Kind regards,

Jan-Willem

> On 25 Apr 2017, at 15:56, Steve Ebersole <steve at hibernate.org> wrote:
> 
> Hi Jan-Willem,
> 
> See comments in-line.  
> 
> Overall though, I wanted to mention that starting in 6.0 we will be introducing a redesigned Type SPI to hopefully address some shortcomings, some of which you bring up.  I hope you add your input to some of those discussion threads on this list about that redesign.
> 
> 
> On Mon, Apr 24, 2017 at 2:02 PM Jan-Willem Gmelig Meyling <jan-willem at youngmediaexperts.nl <mailto:jan-willem at youngmediaexperts.nl>> wrote:
> Hi everyone,
> 
> Out of curiosity I’ve tried to implement a UserCollectionType for Guava’s Multimap [1] based on this [2] article thats doing a similar job for Apache’s MultiMap. Doing so I’ve stumbled upon two issues, for which I’d like to receive some feedback.
> 
> As far as I can see, the UserCollectionType seems focussed around mapping values to indexes. In the case of a list this would supposedly be a number, for non-ordered collections I am not sure, but for maps it seems to be the entries' key. It seems that the implementation for Apache’s MultiMap actually is a Map<K, Collection<V>> so that in the UserCollectionType mentioned in that article every index actually points to a collection of values under that key. I am wondering whether this could potentially break the behaviour for the UserCollectionType class as it seems it should be possible to dirty check the values behind the indexes which probably doesn’t work against collections.
> 
> Simply stated (as the article even mentions), Hibernate does not support collections of collections.  In fact JPA even explicitly says this is not supported, although granted implementors can choose to provide such a feature as an extension.  As discussed in the article that would be multi-map support as opposed to map support.  The article shows this can "be done" but this is a case of using something as it was not intended to be used.  
> 
> This is definitely something we would look at supporting in 6.0's type redesign.  Vlad and I have specifically talked about supporting database/JDBC ARRAY types.  That is still quite different from the model described in the article though, so we'd have to see if supporting that kind of model fits in what we want to do or if we can support it with minimal changes.  Again, I'd suggest getting involved in those discussions.
> 
> 
> 
> But there’s another inconvenience I stumbled upon while implementing this. Where the Apache MultiMap extends a Map<K, Object>, Guava’s Multimap does not. I therefore had to override the TypeUtils, JavaXCollectionType, CollectionBinder, ArrtirubteFactory, PluralAttributeImpl, and most likely if I wanted to do it well a MapBinder and PluralAttribute’s CollectionType as well. While doing this I also found out that JavaXCollectionType.getCollectionClass() returns Map.class perfectly fine for the currently supported Map fields, even though they do not satisfy the <? extends Collection> return type.
> 
> So it seems this is a bad idea after all ;-) But I am wondering whether I am missing something here.
> 
> Nope :)  Again, its not something that is supported and it is definitely not baked into these contracts.  We support the Java collection types.  Likely that won't change.  But if its easy enough to add support for other types, we would consider it for 6.0.
> 
>  
> 
> a) Is there a way to map a Map<Key, Collection<Value>> as an EnumeratedCollection in plain Hibernate?
> 
> No.  Again, "collections of collections" are not supported.
> 
>  
> b) Is there another way to achieve the above and persist a Guava Multimap with a custom user type? (Assuming the UserCollectionType is not the right place to start)
> 
> So again no.
> 
>  
> c) Is Hibernate 6 going to change the answer to these questions?
> 
> Yes, supposing someone champions them in the 6.0 type redesign discussions ;)
> 
>  
> d) Was the article ever right about how to persist Apache’s MultiMap’s type, or was it based on false assumptions on the use of UserCollectionType anyways?
>  
> So long as it is true that the nested collection is only ever a "bag"[1], then I could see this possibly working.  I have not looked at the code for the article so I cannot say if it makes that assumption or not.
> 
> [1] An non-ordered, non-unique collection



More information about the hibernate-dev mailing list