=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/AbstractPropertyIntrospectorService.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/AbstractPropertyIntrospectorService.java 2015-03-06 03:20:17 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/schema/AbstractPropertyIntrospectorService.java 2015-03-06 05:27:08 +0000 @@ -30,7 +30,6 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; -import com.google.common.collect.Maps; import org.hibernate.SessionFactory; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.mapping.Collection; @@ -38,6 +37,8 @@ import org.hibernate.mapping.PersistentClass; import org.hibernate.metadata.ClassMetadata; import org.hibernate.persister.collection.CollectionPersister; +import org.hibernate.persister.entity.Joinable; +import org.hibernate.type.AssociationType; import org.hibernate.type.CollectionType; import org.hibernate.type.SingleColumnType; import org.hibernate.type.TextType; @@ -54,6 +55,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.orm.hibernate4.LocalSessionFactoryBean; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -73,7 +75,9 @@ .put( AnalyticalObject.class, BaseAnalyticalObject.class ) .build(); - private Map, Map> classMapCache = Maps.newHashMap(); + protected Map, Map> classMapCache = new HashMap<>(); + + protected Map roleToRole = new HashMap<>(); @Autowired protected ApplicationContext context; @@ -114,6 +118,57 @@ return klass; } + protected void updateJoinTables() + { + if ( !roleToRole.isEmpty() ) + { + return; + } + + Map> joinTableToRoles = new HashMap<>(); + + LocalSessionFactoryBean sessionFactoryBean = getLocalSessionFactoryBean(); + SessionFactoryImplementor sessionFactoryImplementor = (SessionFactoryImplementor) sessionFactory; + Iterator iterator = sessionFactoryBean.getConfiguration().getCollectionMappings(); + + while ( iterator.hasNext() ) + { + Collection collection = (Collection) iterator.next(); + CollectionPersister persister = sessionFactoryImplementor.getCollectionPersister( collection.getRole() ); + + if ( persister.isManyToMany() && collection.getType().isAssociationType() ) + { + AssociationType associationType = (AssociationType) collection.getType(); + Joinable associatedJoinable = associationType.getAssociatedJoinable( sessionFactoryImplementor ); + + if ( !joinTableToRoles.containsKey( associatedJoinable.getTableName() ) ) + { + joinTableToRoles.put( associatedJoinable.getTableName(), new ArrayList() ); + } + + joinTableToRoles.get( associatedJoinable.getTableName() ).add( collection.getRole() ); + } + } + + Iterator>> entryIterator = joinTableToRoles.entrySet().iterator(); + + while ( entryIterator.hasNext() ) + { + Map.Entry> entry = entryIterator.next(); + + if ( entry.getValue().size() < 2 ) + { + entryIterator.remove(); + } + } + + for ( Map.Entry> entry : joinTableToRoles.entrySet() ) + { + roleToRole.put( entry.getValue().get( 0 ), entry.getValue().get( 1 ) ); + roleToRole.put( entry.getValue().get( 1 ), entry.getValue().get( 0 ) ); + } + } + /** * Introspect a class and return a map with key=property-name, and value=Property class. * @@ -130,6 +185,7 @@ @SuppressWarnings( "unused" ) protected Map getPropertiesFromHibernate( Class klass ) { + updateJoinTables(); ClassMetadata classMetadata = sessionFactory.getClassMetadata( klass ); // is class persisted with hibernate @@ -176,9 +232,11 @@ if ( property.isOwner() ) { property.setOwningRole( collectionType.getRole() ); + property.setInverseRole( roleToRole.get( collectionType.getRole() ) ); } else { + property.setOwningRole( roleToRole.get( collectionType.getRole() ) ); property.setInverseRole( collectionType.getRole() ); } }