[hibernate-dev] JPA Events

Petar Tahchiev paranoiabla at gmail.com
Wed Mar 21 02:35:10 EDT 2018


Hi guys,

any idea how to overcome this? Like I said, when I create my JPA listener
with the following:

@Override
public void onPreUpdateCollection(PreCollectionUpdateEvent event) {
    super.touchForUpdate(event.getAffectedOwnerOrNull());
    updateCollectionOwner(event);
}


private void updateCollectionOwner(AbstractCollectionEvent event) {
    AbstractEntityDefinition aem = (AbstractEntityDefinition)
event.getAffectedOwnerOrNull();

    if (aem != null) {
        EntityManagerFactory emf =
ApplicationContextProvider.getApplicationContext().getBean("entityManagerFactory",
EntityManagerFactory.class);
        EntityManager em =
EntityManagerFactoryUtils.getTransactionalEntityManager(emf);
        try {
            LOG.debug("Updating lastModifiedDate of: {}", aem.getEntityName());
            String hql = "UPDATE " + aem.getEntityName() + " SET " +
LAST_MODIFIED_ATTRIBUTE + " = :attr WHERE id = :id";
            Query updateQuery = em.createQuery(hql);
            updateQuery.setParameter("attr", aem.getLastModifiedDate());
            updateQuery.setParameter("id", aem.getId());
            int result = updateQuery.executeUpdate();
            LOG.debug(String.valueOf(result));
        } catch (Exception ex) {
            LOG.error(ex.getMessage(), ex);
        }
    }
}


Then I get stackoverflow, because when

updateQuery.executeUpdate();

is called, then another PreCollectionUpdateEvent is raised (even though as
you can see in my query I am only updating the LAST_MODIFIED_ATTRIBUTE and
no other field). Is this a bug? Why is PrecollectionUpdateEvent fired when
I am only updating one field of type LocalDateTime?




2018-03-19 20:01 GMT+02:00 Petar Tahchiev <paranoiabla at gmail.com>:

> Hi Steve,
>
> thank you for your reply. I really appreciate it. Here's my situation: my
> client asked me to get the dirty Products. Now the Product has a
> List<String> manufacturers so to me it is obvious that when the
> manufacturers are changed then the Product is dirty, and this is exactly
> what I try to achieve.
> Unfortunately I can't do this - neither with JPA, nor with Hibernate
> directly.
>
> - JPA has only @PreUpdate and @PrePersist which are not invoked if the
> List<String> manufacturers are changed.
>
> - Hibernate however has several more listeners (
> PreCollectionUpdateEventListener, PreCollectionRemoveEventListener,
> PreCollectionRecreateEventListener). So I created my own EventListeners
> and implement those interfaces. Now when the Collection<String> is
> modified, I set the Product.isDirty flag to TRUE and try to save the
> Product. Unfortunately the moment I do that then another
> PreCollectionUpdate is fired so I get a StackOverflow error. I was thinking
> to update the product directly with JDBC and bypass Hibernate, but
> unfortunately my client has requested the solution to be database agnostic
> and so using plain JDBC will bring me a lot of troubles.
>
> I can, however, implement my requirements with EclipseLink, as noted in
> this comment:
>
> https://github.com/javaee/jpa-spec/issues/167#issuecomment-374254412
>
> But I really like Hibernate and I don't want to migrate all my code to
> EclipseLink :(
>
> What does the rest of the Hibernate team think? I know it's a matter of
> interpretation of the spec, but is it really going to be a big change if
> PreUpdate events were fired when a List<String> or a Map<String, String>
> attributes are changed?
>
>
> 2018-03-19 17:32 GMT+02:00 Steve Ebersole <steve at hibernate.org>:
>
>> It is actually very unclear.  Look at the wording... "...update
>> operations to *entity* data...".  So clearly it boils down to your
>> definition of "entity data" and what is being updated, as Oliver mentions
>> as well.  We take the interpretation that since we are not updating the
>> entity table here, we do not fire the event (unless the entity is
>> versioned, in which case the change in the collection would cause a version
>> increment and the entity table to be updated as well).
>>
>> In Hibernate, this would translate to a collection event - but of course
>> JPA has no such notion.  And the distinction is actually quite important
>> for supporting things like Envers, so it would need to be a VERY compelling
>> reason to change this behavior in Hibernate.
>>
>> On Mon, Mar 19, 2018 at 9:55 AM Petar Tahchiev <paranoiabla at gmail.com>
>> wrote:
>>
>>> Hi guys,
>>>
>>> I opened an issue in the JPA spec here yesterday:
>>>
>>> https://github.com/javaee/jpa-spec/issues/167
>>>
>>> because @PreUpdate and @PrePersist events are not fired when I save a
>>> collection on the owner. Since then, a discussion with Oliver Gierke from
>>> the SpringDATA team started and I wanted to know your opinion on this.
>>>
>>> Basically the question is: if you have Product with a Collection<String>
>>> attribute and you update the collection, shall @PreUpdate event be fired.
>>>
>>> As Oliver mentioned the JPA spec says:
>>> -------
>>> The PreUpdate and PostUpdate callbacks occur before and after the
>>> database
>>> update operations to entity data respectively.
>>> -------
>>>
>>> so to me it is obvious that when an attribute of the Product is changed
>>> then this means that @PreUpdate event for the Product must be fired.
>>>
>>> What do you think? Should I open a bug in Hibernate?
>>>
>>> --
>>> Regards, Petar!
>>> Karlovo, Bulgaria.
>>> ---
>>> Public PGP Key at:
>>> http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x19658550C3110611
>>> Key Fingerprint: A369 A7EE 61BC 93A3 CDFF  55A5 1965 8550 C311 0611
>>> _______________________________________________
>>> hibernate-dev mailing list
>>> hibernate-dev at lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>>
>>
>
>
> --
> Regards, Petar!
> Karlovo, Bulgaria.
> ---
> Public PGP Key at: http://pgp.mit.edu:11371/pks/lookup?op=get&search=
> 0x19658550C3110611
> Key Fingerprint: A369 A7EE 61BC 93A3 CDFF  55A5 1965 8550 C311 0611
>



-- 
Regards, Petar!
Karlovo, Bulgaria.
---
Public PGP Key at:
http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x19658550C3110611
Key Fingerprint: A369 A7EE 61BC 93A3 CDFF  55A5 1965 8550 C311 0611


More information about the hibernate-dev mailing list