-->
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: Persisting a Map containing interfaces (Hibernate 4.0.1)
PostPosted: Wed Mar 07, 2012 8:16 am 
Newbie

Joined: Wed Mar 07, 2012 7:44 am
Posts: 2
I've spent hours (and hours!) trying to figure this out myself and I'm going bonkers - I need help please with @ManyToAny. First a bit of background:

What I'm trying to do is straightforward and must be quite common now that we're all using generics and coding to interfaces rather than implementations. I have an entity that contains a Map (LinkedHashMap as it happens) of other entities. The Map is generic, and the generic type (DataChangeListener) is an interface:
Code:
    private Map<Long, DataChangeListener> changeListeners       = new LinkedHashMap<Long, DataChangeListener>();

The DataChangeListener interface is straightforward enough (HasID is another interface that mandates the get/setID() fields but I've overridden them in this interface too in case it helps!):
Code:
public interface DataChangeListener extends HasID
{
    @Override
    public long getID();

    @Override
    public void setID(long newID);

    public void listenedDataHasChanged(DataChangeEvent event);
}

I've figured-out that I can't just use @OneToMany on the Map, because it's typed with an interface not an abstract class or implementation. (that's a pity, but I can understand why this doesn't work). So, I realised that @ManyToAny is the solution to my problems! (@OneToAny would be ideal but doesn't exist) It allows me to tell Hibernate to use TWO columsn (in a separate table as it is @ManytoAny not @OneToAny) that contain both the primary key of the DataChangeListener but also an implementor type-flag so Hibernate knows what the implementation class of the DataChangeListener interface is. Everything seems great. Except.... when I annotate using the following:
Code:
    @AnyMetaDef(name = "DataChangeListeners", idType = "long", metaType = "string", metaValues = { @MetaValue(value = "DynamicMonthImpl", targetEntity = DynamicMonthImpl.class) })
    @ManyToAny(metaDef = "DataChangeListeners", metaColumn = @Column(name = "listener_type"))
    @JoinTable(name = "DatachangeManagerToListenersMapping", joinColumns = { @JoinColumn(name = "listenerID", referencedColumnName = "iD") }, inverseJoinColumns = @JoinColumn(name = "dataChangeManagerID", referencedColumnName = "iD"))
    private Map<Long, DataChangeListener> changeListeners       = new LinkedHashMap<Long, DataChangeListener>();

I get an error on deployment as follows:
Code:
Caused by: java.lang.UnsupportedOperationException: collection of any not supported yet
   at org.hibernate.ejb.metamodel.AttributeFactory.determineAttributeMetadata(AttributeFactory.java:455)
   at org.hibernate.ejb.metamodel.AttributeFactory.buildAttribute(AttributeFactory.java:91)
   at org.hibernate.ejb.metamodel.MetadataContext.wrapUp(MetadataContext.java:185)
   at org.hibernate.ejb.metamodel.MetamodelImpl.buildMetamodel(MetamodelImpl.java:64)
   at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:91)
   at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:904)
   at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:889)
   at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:73)
   at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.createContainerEntityManagerFactory(PersistenceUnitServiceImpl.java:162)
   at org.jboss.as.jpa.service.PersistenceUnitServiceImpl.start(PersistenceUnitServiceImpl.java:85)
   at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
   at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746) [jboss-msc-1.0.2.GA.jar:1.0.2.GA]
   ... 3 more

But I can't figure out why. Firstly, Map isn't a Collection (but I guess the exception is thrown because somewhere inside the LinkedHashMap implementation there is a Collection?). Secondly though, if this function doesn't work with Collection instances, how do I persist my Map?

This must be a REALLY common use-case, surely? I have looked through my class model, and I can't change DataChangeListener to be an abstract class even if I wanted-to (no multiple-inheritance in Java, and DataChangeListener isn't the only interface in the heirarchy) - and it feels wrong to have to remove interfaces from the model when they are such a powerful feature of the language.

Maybe I have to drop Map altogether and use a List? That would be considerable less efficient in-use (I'd have to iterate-over all instances to find the one I want).

Where am I going wrong guys? How does everyone else handle this?

TIA! James.


Top
 Profile  
 
 Post subject: hibernate.ejb.metamodel.generation=disabled - ??
PostPosted: Wed Mar 07, 2012 6:45 pm 
Newbie

Joined: Wed Mar 07, 2012 7:44 am
Posts: 2
Another day on it and I'm off to the races. I found some references to a hibernate property that when set to disabled allows the code to deploy, tables to be created and objects persisted. Everything seems great in fact! The quesiton now is, what are the implications of setting the following property in persistence.xml:
Code:
hibernate.ejb.metamodel.generation=disabled

?
Am I going to find that I'm missing something fundamental later-on down the road?

Thanks, James.


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.