=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/preheat/DefaultPreheatService.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/preheat/DefaultPreheatService.java 2016-03-13 11:05:30 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/preheat/DefaultPreheatService.java 2016-03-14 01:56:52 +0000 @@ -61,6 +61,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -683,17 +684,25 @@ return objectErrorReports; } - for ( int i = 0; i < objects.size(); i++ ) + Iterator iterator = objects.iterator(); + int idx = 0; + + while ( iterator.hasNext() ) { - IdentifiableObject object = objects.get( i ); + IdentifiableObject object = iterator.next(); + List errorReports = checkUniqueness( object, preheat, identifier ); - if ( errorReports.isEmpty() ) continue; - - ObjectErrorReport objectErrorReport = new ObjectErrorReport( object.getClass(), i ); - objectErrorReport.addErrorReports( errorReports ); - objectErrorReports.add( objectErrorReport ); - + if ( !errorReports.isEmpty() ) + { + ObjectErrorReport objectErrorReport = new ObjectErrorReport( object.getClass(), idx ); + objectErrorReport.addErrorReports( errorReports ); + objectErrorReports.add( objectErrorReport ); + + iterator.remove(); + } + + idx++; } return objectErrorReports; @@ -706,10 +715,13 @@ if ( object == null || Preheat.isDefault( object ) ) return errorReports; + if ( !preheat.getUniquenessMap().containsKey( object.getClass() ) ) + { + preheat.getUniquenessMap().put( object.getClass(), new HashMap<>() ); + } + Map> uniquenessMap = preheat.getUniquenessMap().get( object.getClass() ); - if ( uniquenessMap == null ) return errorReports; - Schema schema = schemaService.getDynamicSchema( object.getClass() ); List uniqueProperties = schema.getProperties().stream() .filter( p -> p.isPersisted() && p.isOwner() && p.isUnique() ) @@ -733,6 +745,15 @@ } } } + else + { + if ( !uniquenessMap.containsKey( property.getName() ) ) + { + uniquenessMap.put( property.getName(), new HashMap<>() ); + } + + uniquenessMap.get( property.getName() ).put( value, object.getUid() ); + } } } ); === modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/DefaultObjectBundleService.java' --- dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/DefaultObjectBundleService.java 2016-03-13 11:05:30 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/main/java/org/hisp/dhis/dxf2/metadata2/objectbundle/DefaultObjectBundleService.java 2016-03-14 01:56:52 +0000 @@ -117,11 +117,14 @@ { if ( bundle.getImportMode().isCreateAndUpdate() ) { - objectBundleValidation.addObjectErrorReports( validateBySchemas( klass, bundle.getObjectMap().get( klass ), bundle ) ); + objectBundleValidation.addObjectErrorReports( validateBySchemas( klass, bundle.getObjects( klass, false ), bundle ) ); + objectBundleValidation.addObjectErrorReports( validateBySchemas( klass, bundle.getObjects( klass, true ), bundle ) ); + + objectBundleValidation.addObjectErrorReports( preheatService.checkUniqueness( bundle.getObjects( klass, false ), bundle.getPreheat(), + bundle.getPreheatIdentifier() ) ); + objectBundleValidation.addObjectErrorReports( preheatService.checkReferences( bundle.getObjectMap().get( klass ), bundle.getPreheat(), bundle.getPreheatIdentifier() ) ); - objectBundleValidation.addObjectErrorReports( preheatService.checkUniqueness( bundle.getObjectMap().get( klass ), bundle.getPreheat(), - bundle.getPreheatIdentifier() ) ); } if ( bundle.getImportMode().isCreate() ) === modified file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleServiceTest.java' --- dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleServiceTest.java 2016-03-13 10:19:38 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/test/java/org/hisp/dhis/dxf2/metadata2/objectbundle/ObjectBundleServiceTest.java 2016-03-14 01:56:52 +0000 @@ -1389,6 +1389,30 @@ assertEquals( 1, validate.getErrorReportsByCode( UserAuthorityGroup.class, ErrorCode.E5003 ).size() ); } + @Test + public void testCreateMetadataWithDuplicateDataElementCode() throws IOException + { + createUserAndInjectSecurityContext( true ); + + Map, List> metadata = renderService.fromMetadata( + new ClassPathResource( "dxf2/de_duplicate_code.json" ).getInputStream(), RenderFormat.JSON ); + + ObjectBundleParams params = new ObjectBundleParams(); + params.setObjectBundleMode( ObjectBundleMode.COMMIT ); + params.setImportMode( ImportStrategy.CREATE_AND_UPDATE ); + params.setObjects( metadata ); + + ObjectBundle bundle = objectBundleService.create( params ); + objectBundleService.validate( bundle ); + objectBundleService.commit( bundle ); + + assertEquals( 1, manager.getAll( DataElement.class ).size() ); + + DataElement dataElement = manager.getByCode( DataElement.class, "DataElementCodeA" ); + assertEquals( "SG4HuKlNEFH", dataElement.getUid() ); + assertEquals( "DataElementA", dataElement.getName() ); + } + private void defaultSetup() { DataElement de1 = createDataElement( 'A' ); === added file 'dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/de_duplicate_code.json' --- dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/de_duplicate_code.json 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-services/dhis-service-dxf2/src/test/resources/dxf2/de_duplicate_code.json 2016-03-14 01:56:52 +0000 @@ -0,0 +1,48 @@ +{ + "dataElements": [ + { + "attributeValues": [ ], + "userGroupAccesses": [ ], + "valueType": "TEXT", + "aggregationType": "SUM", + "created": "2016-02-17T06:15:06.079+0000", + "shortName": "DataElementShortA", + "categoryCombo": { + "id": "zU1OZFVxnw7" + }, + "aggregationLevels": [ ], + "id": "SG4HuKlNEFH", + "domainType": "AGGREGATE", + "lastUpdated": "2016-02-17T06:15:59.378+0000", + "user": { + "id": "ueKaFVdR8Fz" + }, + "zeroIsSignificant": false, + "publicAccess": "rw------", + "code": "DataElementCodeA", + "name": "DataElementA" + }, + { + "code": "DataElementCodeA", + "publicAccess": "rw------", + "name": "DataElementB", + "attributeValues": [ ], + "userGroupAccesses": [ ], + "valueType": "TEXT", + "aggregationType": "SUM", + "shortName": "DataElementShortB", + "created": "2016-02-17T06:15:49.487+0000", + "categoryCombo": { + "id": "zU1OZFVxnw7" + }, + "id": "CCwk5Yx440o", + "aggregationLevels": [ ], + "domainType": "AGGREGATE", + "user": { + "id": "ueKaFVdR8Fz" + }, + "lastUpdated": "2016-02-17T06:16:08.180+0000", + "zeroIsSignificant": false + } + ] +} \ No newline at end of file