Thanks, Please send a Pull Request with a replicating test case.
Vlad On Wed, Dec 28, 2016 at 12:05 AM, Milo van der Zee <m...@vanderzee.org> wrote: > Hello all, > > During development of applications I'm used to set the schema creation > to 'update' (hbm2ddl.auto = update). This makes life a bit easier. > Issue with the newer version of Hibernate is that the name of the > generated keys changed and so all keys are regenerated. For the large > databases I use this takes hours and has to be done every time a fresh > copy from production is taken to the development environment. > > I do use meaningful names for the indexes where possible. But when using > abstract classes used by the entities that is not possible because the > same fields from the abstract are used by many entity classes and so > would end up having the same index names. > > I checked the code that decides if the index needs to be created and > found that it only checks the name of the index. Not what the index > actually does. This is why I changed that piece of code to be a bit > smarter. It is desinged for simple constraints from one column to > another column. Not for multi to multi column indexes and constraints. > > I created a Jira issue for it but nobody notices it and there are no > comments or anything else. So now I try it here :) > Jira HHH-10934 (https://hibernate.atlassian.net/browse/HHH-10934) > > Code fragment I put in SchemaMigratorImpl.java: > > private ForeignKeyInformation findMatchingForeignKey(ForeignKey > foreignKey, TableInformation tableInformation) { > if (foreignKey.getName() ==null) { > return null; > } > > /* > * Find existing keys based on referencing column and > referencedTable > */ > String referencingColumn = foreignKey.getColumn(0).getName(); > String referencedTableName = foreignKey.getReferencedTable( > ).getName(); > Iterable<ForeignKeyInformation> existingForeignKeys = > tableInformation.getForeignKeys(); > for (ForeignKeyInformation existingKey : existingForeignKeys) { > Iterable<ColumnReferenceMapping> columnReferenceMappings > = existingKey.getColumnReferenceMappings(); > for (ColumnReferenceMapping mapping : > columnReferenceMappings) { > String existingReferencingColumn = mapping. > getReferencingColumnMetadata().getColumnIdentifier().getText(); > String existingReferencedTableName = mapping. > getReferencedColumnMetadata().getContainingTableInformation( > ).getName().getTableName().getCanonicalName(); > if > (referencingColumn.equals(existingReferencingColumn) > && referencedTableName.equals(existingReferencedTableName)) { > return existingKey; > } > } > } > > // If not yet found check based on key name return > tableInformation.getForeignKey(Identifier.toIdentifier(foreignKey. > getName())); > } > > Or if you prever the Java 8 way: > > private ForeignKeyInformation findMatchingForeignKey(ForeignKey > foreignKey, TableInformation tableInformation) { > log.debug("findMatchingForeignKey"); > if (foreignKey.getName() ==null)return null; > > /* > * Find existing keys based on referencing column and > referencedTable > */ > String referencingColumn = foreignKey.getColumn(0).getName(); > String referencedTableName = foreignKey.getReferencedTable( > ).getName(); > Predicate<ColumnReferenceMapping> mappingPredicate = m -> > referencingColumn.equals(m.getReferencingColumnMetadata() > .getColumnIdentifier().getText()) > && referencedTableName.equals(m. > getReferencedColumnMetadata().getContainingTableInformation( > ).getName().getTableName().getCanonicalName()); > for (ForeignKeyInformation existingKey : > tableInformation.getForeignKeys()) > { > boolean found = StreamSupport.stream(existingKey. > getColumnReferenceMappings().spliterator(),false).anyMatch( > mappingPredicate); > if (found)return existingKey; > } > > // If not yet found check based on key name return > tableInformation.getForeignKey(Identifier.toIdentifier(foreignKey. > getName())); > } > > The calling method does not use the returned value. It only checks if > the returned value is null or not. So this could also be cleaned by > changing the method to return a boolean and then remove the for loop in > java-8 and use flatmap. But first let us agree on the validity of the > idea to change this piece of code. > > I hope anybody would like to have a look at it and if there is any > change that the idea (not this actual very quick/dirty implementation) > goes into the system I'll clean it up and do some actual tests for more > complex database structures. I did not even check the junit tests yet. > At the moment it is good enough for me but I think it could be something > more people would benefit from. > > Thanks, > Milo van der Zee > > > _______________________________________________ > hibernate-dev mailing list > hibernate-dev@lists.jboss.org > https://lists.jboss.org/mailman/listinfo/hibernate-dev > _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev