Finally done... See https://github.com/hibernate/hibernate-orm/pull/1906
MAG, Milo On 01/09/2017 01:02 PM, Vlad Mihalcea wrote: > 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 > <mailto: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 > <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 <mailto:hibernate-dev@lists.jboss.org> > https://lists.jboss.org/mailman/listinfo/hibernate-dev > <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