Preventing duplicate ForeignKey generation
by Milo van der Zee
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
7 years, 7 months
Javassist dependency conflict in the ORM modules for WildFly
by Sanne Grinovero
Hi all,
there's a conflict in the Javassist versions of the WildFly modules of
Hibernate ORM 5.2.4.Final, but I'm not sure how to proceed as I'm not
familiar with this functionality.
The module declares *both*:
- a dependency to the WildFly provided Javassist: <module
name="org.javassist"/>
- inclusion of Hibernate's own version of Javassist: <resource-root
path="javassist-3.20.0-GA.jar"/>
Having both is causing trouble as they are both visible to the
Hibernate classloader; however I couldn't score a quick win with the
testsuiste by disabling either (all tests using these modules in the
Hibernate Search testsuite fail).
I suspect the problem is that JipiJapa also depends on the <module
name="org.javassist"/>, while ORM obviously needs the more recent
version of it.
I'm not familiar with what JipiJapa's business around Javassist; could
we keep the two clearly separated?
Especially if we want to make Byte Buddy a viable alternative, I
suspect the solution is that JipiJapa should not depend on Javassist
directly, but invoke a generic instrumentation SPI on Hibernate; also
with JipiJapa not able to see Javassist at all, we'd be in control of
the one and only Javassist version visible to ORM: the one we compile
and test with.
Thanks,
Sanne
7 years, 9 months
6.0 - Proposed org.hibernate.mapping changes
by Steve Ebersole
For 6.0, what do y'all think of these changes proposed below to the
org.hibernate.mapping package?
*Koen, this affects tools so really would like your thoughts...*
Mostly this comes from the definition of a `#finishInitialization` method
on ManagedTypeImplementor (which covers mapped-superclass, entity and
embeddable/embedded). Currently this method takes its supertype as
PersistentClass; however PersistentClass is generally understood to model
an entity and tooling certainly uses it as such. Keeping this in mind to
hopefully minimize impact I propose the following:
1. Define a new org.hibernate.mapping.ManagedTypeMapping that represents
mappings for any "managed type" in the normal JPA meaning of that term
(mapped-superclass, entity, embeddable)
2. Define a new org.hibernate.mapping.EmbeddedTypeMapping extending
ManagedTypeMapping (org.hibernate.mapping.Composite). Or should we split
EmbeddableTypeMapping and "EmbeddedMapping"?
3. Define a new org.hibernate.mapping.IdentifiableTypeMapping extending
ManagedTypeMapping
4. Define a new org.hibernate.mapping.MappedSuperclassTypeMapping
extending IdentifiableTypeMapping
5. Define a new org.hibernate.mapping.EntityTypeMapping extending
IdentifiableTypeMapping
6. Make PersistentClass extend EntityTypeMapping and deprecate
7. Make Composite extend EmbeddedTypeMapping and deprecate
8. Make MapppedSuperclass extend MappedSuperclassTypeMapping and
deprecate
9. Re-work the hierarchies here to better fit this new model
/**
* ...
*
* @todo (6.0) Use ManagedTypeMapping here as super-type rather than
PersistentClass
*/
void finishInitialization(
ManagedTypeImplementor<? super T> superType,
PersistentClass entityBinding,
PersisterCreationContext creationContext);
7 years, 9 months
Can someone confirm if DB2 9.5 supports "cross join"?
by Gail Badner
I created HHH-11499 to create a new dialect for DB2 to use "cross join"
syntax instead of "," (as is currently done in DB2Dialect).
Although DB2 9.1 reached its end of life April 30, 2015, some applications
may still be using that version, so I will create a new DB2 dialect that
extends DB2Dialect and overrides getCrossJoinSeparator() to return " cross
join ".
The question is what to call the new dialect.
According to DB2 9.5 and 9.7 documentation, "cross join" syntax is
supported in those versions. I am able to confirm this on 9.7, but I do not
have access to DB2 9.5 to try it out.
If someone can confirm this will work on DB2 9.5 by the time Hibernate
5.2.9 is released, then I'll name the new dialect DB295Dialect; otherwise,
I'll name it DB297Dialect.
Thanks!
Gail
7 years, 9 months
HHH-11144
by Gail Badner
HHH-11144 involves an entity that has 2 one-to-many associations with the
same type of entity, and both associations have orphanRemoval = true.
Andrea created a PR with test case at [1]
I am not sure if this is a valid mapping. I I would like your thoughts on
this.
Here is an excerpt of the relevant bits:
@Entity(name = "Item")
public static class Item {
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval
= true)
protected Set<ItemRelation> lowerItemRelations = new LinkedHashSet<>();
@OneToMany(mappedBy = "child", cascade = CascadeType.ALL, orphanRemoval =
true)
protected Set<ItemRelation> higherItemRelations = new LinkedHashSet<>();
}
@Entity(name = "ItemRelation")
public static class ItemRelation {
@ManyToOne(optional = false)
@JoinColumn(name = "PARENT_ID")
private Item parent;
@ManyToOne(optional = false)
@JoinColumn(name = "CHILD_ID")
private Item child;
}
HHH-11144 describes inconsistent behavior observed when
Item#lowerItemRelations and Item#higherItemRelations both contain the same
ItemRelation, then one of the collections is cleared.
If the non-cleared collection is uninitialized, then the ItemRelation is
orphan deleted.
If the non-cleared collection is initialized, then the orphan-deleted
ItemRelation is rescued when PERSIST_ON_FLUSH cascades to the non-cleared
collection elements. The next time the collections are loaded from the
database, both will still contain that same ItemRelation.
The spec says:
"Portable applications must otherwise not depend upon a specific order of
removal, and must not reassign an entity that has been orphaned to another
relationship or *otherwise attempt to persist it*"
Is Hibernate doing the right thing by rescuing an orphan-deleted entity?
In addition, this mapping allows a particular EntityRelation to be
associated with 2 different Item entities, which would mean that the same
ItemRelation would have 2 different owners with respect to orphan deletion..
The spec says:
"The orphanRemoval functionality is intended for entities that are privately
“owned” by their parent entity."
Does this mean that the mapping is invalid, since it would allow multiple
parent entities, or does it mean that the resulting behavior is undefined
(thus non-portable)?
Please let me know your thoughts.
Thanks,
Gail
[1] https://github.com/hibernate/hibernate-orm/pull/1607
7 years, 9 months
NoORM IRC meeting minutes
by Guillaume Smet
Hi,
The minutes are there:
16:03 < jbott> Ending meeting. Generating minutes. Be patient :)
16:03 < jbott> Meeting ended Tue Feb 28 15:03:46 2017 UTC. Information
about MeetBot at http://wiki.debian.org/MeetBot . (v 0.1.4)
16:03 < jbott> Minutes:
http://transcripts.jboss.org/meeting/irc.freenode.org/hibernate-dev/2017/...
16:03 < jbott> Minutes (text):
http://transcripts.jboss.org/meeting/irc.freenode.org/hibernate-dev/2017/...
16:03 < jbott> Log:
http://transcripts.jboss.org/meeting/irc.freenode.org/hibernate-dev/2017/...
The start of the meeting (Davide's part) is missing. Here it is:
15:02 < gsmet> #topic Progress Davide
15:02 < gmorling> i can literally hear the cracking of @gsmet’s whip ;)
15:02 < DavideD> So this week I clean up a bit the Hibernate OGM
documentation and added a testcase to check the mapping in the remote case
15:03 -!- hardy [~hardy@redhat/jboss/hardy] has quit [Read error:
Connection reset by peer]
15:03 < DavideD> The idea is to release 5.1.Final today so that I can start
to include the changes for 5.2
15:03 -!- hardy [~hardy@redhat/jboss/hardy] has joined #hibernate-dev
15:03 < gsmet> OK, cool
15:03 < DavideD> While doing that I found an error in the mapping for Neo4j
15:03 -!- rvansa [rvansa@nat/redhat/x-zpsbqauumvnztuke] has quit [Ping
timeout: 260 seconds]
15:04 < DavideD> So It slowed me down a bit, but It should have been fix
now and I'm sending a PR
15:04 < gmorling> cool with the release; what version of orm is it based on
again?
15:04 < emmanuel> @DavideD I had a discussion with Sanne on 5.2 as there
seem there was confusion on what 5.2 was vs 5.3
15:04 -!- sannegrinovero_ [~sannegrin@redhat/jboss/sannegrinovero] has
joined #hibernate-dev
15:04 < gsmet> DavideD: a new PR on top of what has already been committed
this morning?
15:04 < DavideD> gsmet, yes
15:04 < emmanuel> make sure to check again the paper midnmap picture that
we took at the f2f
15:04 < gsmet> ok
15:04 < sannegrinovero_> hi all
15:05 < DavideD> I've figured out why the bolt job is not working
15:05 < gsmet> ah, cool, curious to see that :)
15:05 < emmanuel> gmorling: only 5.3 will move to a new ORM version
15:05 < emmanuel> (could be 5.4 if the ISPN 9 work is done first :))
15:06 < DavideD> gmorling, OGM 5.1 is based on ORM 5.1.2
15:06 < gmorling> ok, thanks
15:06 < DavideD> emmanuel, ok
15:06 < gsmet> DavideD: maybe it could be bumped to 5.1.4?
15:06 < gsmet> would make sense before the final release
15:06 < sannegrinovero_> +1
15:07 < DavideD> ok
15:06 < sannegrinovero_> +1
15:07 < DavideD> ok
15:07 < DavideD> I also spent some time On CI
15:08 < DavideD> Now the website job can be run in parallel with the other
jobs
15:08 < gsmet> is it the same for the blog?
15:08 < DavideD> I removed the Blueocean plugin and updated the git plugins
15:08 < DavideD> yes, the blog as well
15:08 < gsmet> cool!
15:08 < DavideD> but if you see that one job does not run in parallel
15:08 < DavideD> you can change the weight
15:09 < sannegrinovero_> FYI I updated the git plugins as well.. yesterday.
15:09 < gsmet> ok
15:09 < DavideD> for example, I didn't update the weight of the release jobs
15:09 < gsmet> ok so now, they are really up to date :)
15:10 < DavideD> well OK
15:10 < DavideD> I think that's all from me
15:10 < gsmet> ok, thanks
15:10 < DavideD> After the release
15:10 < gsmet> #topic Next 2 weeks Davide
15:10 < DavideD> I need to create the new repository for the contrib
dialects
7 years, 9 months
[hibernate-demos] PR and issues and what to do about it
by Emmanuel Bernard
There has been an effort to collect demos under a single repo.
https://github.com/hibernate/hibernate-demos
The good news is that people seem to like it enough that they send pull requests and issue reports to improve it. The bad news is that we did not reply to them. I think it’s because no one is notified of these. Can anyone enlist and be the guardian or even just the dispatcher for this kind of feedback?
I’ve cleaned up and applied a couple of pull requests today.
Emmanuel
7 years, 9 months
Removing the BlueOcean plugin on CI
by Davide D'Alto
Hi.
I'm going to remove the BlueOcean plugin from Ci.
Currently, when we receive an email because a build is failed, the
link to the job is wrong and it seems that BlueOcena is the cause.
I don't think anybody is actually using it but if there are some
objections, let me know.
Regards,
Davide
7 years, 10 months