private boolean isSameAsPrimaryKeyColumns(UniqueKey uniqueKey) { if (primaryKey == null || !primaryKey.columnIterator().hasNext()) { // happens for many-to-many tables return false; } return primaryKey.getColumns().containsAll(uniqueKey.getColumns()) && uniqueKey.getColumns().containsAll(primaryKey.getColumns()); }
private void cleanseUniqueKeyMap() { // We need to account for a few conditions here... // 1) If there are multiple unique keys contained in the uniqueKeys Map, we need to deduplicate // any sharing the same columns as other defined unique keys; this is needed for the // annotation // processor since it creates unique constraints automagically for the user // 2) Remove any unique keys that share the same columns as the primary key; again, this is // needed for the annotation processor to handle @Id @OneToOne cases. In such cases the // unique key is unnecessary because a primary key is already unique by definition. We handle // this case specifically because some databases fail if you try to apply a unique key to // the primary key columns which causes schema export to fail in these cases. if (uniqueKeys.isEmpty()) { // nothing to do return; } else if (uniqueKeys.size() == 1) { // we have to worry about condition 2 above, but not condition 1 final Map.Entry<String, UniqueKey> uniqueKeyEntry = uniqueKeys.entrySet().iterator().next(); if (isSameAsPrimaryKeyColumns(uniqueKeyEntry.getValue())) { uniqueKeys.remove(uniqueKeyEntry.getKey()); } } else { // we have to check both conditions 1 and 2 final Iterator<Map.Entry<String, UniqueKey>> uniqueKeyEntries = uniqueKeys.entrySet().iterator(); while (uniqueKeyEntries.hasNext()) { final Map.Entry<String, UniqueKey> uniqueKeyEntry = uniqueKeyEntries.next(); final UniqueKey uniqueKey = uniqueKeyEntry.getValue(); boolean removeIt = false; // condition 1 : check against other unique keys for (UniqueKey otherUniqueKey : uniqueKeys.values()) { // make sure its not the same unique key if (uniqueKeyEntry.getValue() == otherUniqueKey) { continue; } if (otherUniqueKey.getColumns().containsAll(uniqueKey.getColumns()) && uniqueKey.getColumns().containsAll(otherUniqueKey.getColumns())) { removeIt = true; break; } } // condition 2 : check against pk if (isSameAsPrimaryKeyColumns(uniqueKeyEntry.getValue())) { removeIt = true; } if (removeIt) { // uniqueKeys.remove( uniqueKeyEntry.getKey() ); uniqueKeyEntries.remove(); } } } }
@SuppressWarnings("rawtypes") public void testUniqueConstraintGeneration() { DefaultGrailsDomainConfiguration config = getDomainConfig(UNIQUE_PROPERTIES); assertEquals("Tables created", 1, getTableCount(config)); List expectedKeyColumns1 = Arrays.asList( new Column[] {new Column("camel_cased"), new Column("group"), new Column("login")}); List expectedKeyColumns2 = Arrays.asList(new Column[] {new Column("camel_cased"), new Column("group")}); Table mapping = (Table) config.getTableMappings().next(); int cnt = 0; boolean found1 = false, found2 = false; for (Iterator<?> i = mapping.getUniqueKeyIterator(); i.hasNext(); ) { UniqueKey key = (UniqueKey) i.next(); List keyColumns = key.getColumns(); if (keyColumns.equals(expectedKeyColumns1)) { found1 = true; } if (keyColumns.equals(expectedKeyColumns2)) { found2 = true; } cnt++; } assertEquals(2, cnt); assertEquals(true, mapping.getColumn(new Column("employeeID")).isUnique()); assertEquals(true, found1); assertEquals(true, found2); }