Index: impl/src/java/org/sakaiproject/hierarchy/impl/HierarchyServiceImpl.java =================================================================== --- impl/src/java/org/sakaiproject/hierarchy/impl/HierarchyServiceImpl.java (revision 84013) +++ impl/src/java/org/sakaiproject/hierarchy/impl/HierarchyServiceImpl.java (working copy) @@ -959,6 +959,50 @@ metaDatas.add(metaData); Set[] entitySets = new Set[] { pNodes, metaDatas }; dao.saveMixedSet(entitySets); + /* NORMALLY the code below should not be needed, however, + * we are seeing weird cases where the line above fails to create the metadata + * so the code below is meant to detect that case and correct it by saving + * each separately and realigning the ids manually + */ + if (metaData.getId() == null) { + // something went wrong and we're not sure what so delete pNode + if (pNode.getId() != null) { + dao.delete(pNode); + } + throw new RuntimeException("Metadata didn't save, node was removed: "+pNode); + } else if (pNode.getId() == null) { + // something went wrong and we're not sure what so delete metadata + if (metaData.getId() != null) { + dao.delete(metaData); + } + throw new RuntimeException("Metadata didn't save, metaData was removed: "+metaData); + } else if (!metaData.getId().equals(pNode.getId())) { + // the indexes are off... let's try to get them back in sync + int i = 0; + if (pNode.getId() > metaData.getId()) { + while (i < 100 && metaData.getId() != null && pNode.getId() != metaData.getId()) { + // need to keep saving metaData until it's sequence has caught up + dao.delete(metaData); + // set ID back to null to make it save with a new incremented ID + metaData.setId(null); + dao.save(metaData); + i++; + } + } else { + while (i < 100 && pNode.getId() != null && pNode.getId() != metaData.getId()) { + // need to keep saving node until it's sequence has caught up + dao.delete(pNode); + // set ID back to null to make it save with a new incremented ID + pNode.setId(null); + dao.save(pNode); + i++; + } + } + if (pNode.getId() == null || metaData.getId() == null || pNode.getId() != metaData.getId()) { + // ok we tried, it didn't work, so throw the exception + throw new RuntimeException("Node ID: " + pNode.getId() + " doesn't match Metadata ID: " + metaData.getId()); + } + } } /**