Using Spring boot 2.2 that comes with Hibernate 5.4.9.Final. Since the JPA ‘event system’ is woefully inadequate I want to register a post_collection_xxx listener to handle post_collection_xxx events. These events however are exposing a lot of inner classes so before I go too far with my implementation I figured I would ask if there maybe is a better event to listen to ?
not sure what you mean by “inner classes”, but that’s the way to go.
Thanks for the confirmation. Internal classes are for example what gets returned by calling the getCollection which (I think) returns any instance of a class defined in the o.h.collection.internal package in the PostCollectionUpdateEvent event.
So now I would have to check that so I can safely cast the call to ‘getValue’ since the PersistenCollection itself doesn’t have an easy way of going through the entries in the collection. You don’t even know what type of class the collection itself holds.
It looks like the getStoredSnapshot returns the original values but not sure.
The PostCollectionRemoveEvent and PostCollectionRecreateEvent has the same problem in determining what type the collection holds and iterating through them in a safe way.
If there is documentation you can steer me to that does describe the purpose of these classes in more detail, that’d be great.
That method returns a PersistentCollection
and through getRole()
you can find out the CollectionPersister
by using getCollectionDescriptor()
on org.hibernate.engine.spi.SessionFactoryImplementor#getDomainModel()
. This way you have all the necessary SPI objects needed to interact with the PersistentCollection
.
That got me over the hump and got it kind of working. I created one test case where I get a PostCollectionRecreate event where the collection has 2 entries but the getRole method on it returns null.
Ideas how that is possible ? My test is doing something rather simple:
// user was initialized with 2 roles, test replaces those with 2 different ones:
user.setRoles(getNewRoles());
I first get a PostCollectionRemoveEvent event which correctly has both the role set and contains the elements of the original data; the subsequent PostCollectionRecreate has the new data in the collection but like I stated the role is null. Now when I attempt to get the persister by calling implementor.collectionPersister(collection.getRole());
I get a null pointer exception.
Seems like a bug to me (interestingly the CollectionRecreateAction constructor has the correct persister but the collection that is passed already has the role unset) but if you know of a workaround, I’d appreciate it.
Bas
Sorry, but this is a quite involved issue that seems to touch internals. If you think there is a bug, please create an issue in the issue tracker(https://hibernate.atlassian.net) with a test case(https://github.com/hibernate/hibernate-test-case-templates/blob/master/orm/hibernate-orm-5/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java) that reproduces the issue.
I’ll check what kinds of test cases already exist around this and see if I can reproduce it that way; thanks for the help sofar.
Looks like this constructor is the culprit: public CollectionEntry(CollectionPersister persister, PersistentCollection collection)
It is the only constructor in that class that does not call setLoadedPersister
and that method sets the role by calling persister.getRole()