# Unable to pass the listeners (callback) to HBM

**URL:** <https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889>\
**Category:** Hibernate ORM\
**Created:** [January 22, 2024, 2:57pm UTC](https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889 "2024-01-22T14:57:35Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![boutss](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/boutss/32/1543_2.png) [@boutss](https://discourse.hibernate.org/u/boutss)\
**Post date:** [January 22, 2024, 2:57pm UTC](https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889/1 "2024-01-22T14:57:35Z")

</div>

Hello,

I am in the process of defining the mapping of an object via an hbm.xml file because inheritance is not working correctly and is preventing the use of standard annotations.

I have almost managed to do everything, but I am unable to provide the definition for the @EntityListeners.

I have the impression that CallbackDefinition on the PersistentClass is only populated with annotations. I even tried adding it by default, but it doesn’t work for HBM entities.

Basically, I have the impression that for HBM, there is nothing to transmit the listeners, but that seems strange to me. Am I missing something?

I have debugged quite a bit before asking you.

Thank you very much.

[Guide events-default-listener](https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#events-default-listener)

 ![image](https://canada1.discourse-cdn.com/flex035/uploads/hibernate/original/2X/6/62fdc75f793f11cbe0ef50c2e0024f1a05e57258.png)

![image](https://canada1.discourse-cdn.com/flex035/uploads/hibernate/original/2X/6/655ea7b5da6f1ea3e374b21e40093cc6e7ff4597.png)

 ![image](https://canada1.discourse-cdn.com/flex035/uploads/hibernate/original/2X/7/704116c01626c4707a377dc46aa65e2270ef583e.png)

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [January 22, 2024, 5:41pm UTC](https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889/2 "2024-01-22T17:41:06Z")

</div>

Please try to create a reproducer with our test case template ([hibernate-test-case-templates/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java at main · hibernate/hibernate-test-case-templates · GitHub](https://github.com/hibernate/hibernate-test-case-templates/blob/master/orm/hibernate-orm-6/src/test/java/org/hibernate/bugs/JPAUnitTestCase.java)) and if you are able to reproduce the issue, create a bug ticket in our issue tracker([https://hibernate.atlassian.net](https://hibernate.atlassian.net)) and attach that reproducer.

---

<div class="post-metadata">

**Author:** ![boutss](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/boutss/32/1543_2.png) [@boutss](https://discourse.hibernate.org/u/boutss)\
**Post date:** [January 23, 2024, 3:19pm UTC](https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889/3 "2024-01-23T15:19:54Z")

</div>

Actually, I can’t run a test to demonstrate the case because I don’t have the ability to specify a callback to a mapping definition via HBM precisely.

I can show you the HBM mapping.

```auto
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hermes.ref.acteur.businessobject" >

    <class name="ActeurInterne" table="TACTEURINTERNE">

        <discriminator column="ROLE" length="80"/>

        <id name="idHibernate">
            <column name="ID" length="25"/>
            <generator class="com.efluid.hibernate.core.EfluidGeneratorIdentifiant"/>
        </id>

        <property name="acteurCreation" length="50"/>
        <property name="acteurModification" length="50"/>
        <property name="acteurSuppression" length="50"/>
        <property name="dateCreation"/>
        <property name="dateModification"/>
        <property name="dateSuppression"/>
        <property name="etatObjet">
            <column name="ETATOBJET" sql-type="number(1,0)"/>
        </property>
        <property name="agence" length="25"/>

        <subclass name="EntiteAdministrative"
                  discriminator-value="com.hermes.ref.acteur.businessobject.EntiteAdministrative">
            <property name="categorieEntite" length="80"/>
        
        </subclass>

        <subclass name="Agent" discriminator-value="com.hermes.ref.acteur.businessobject.Agent">

        </subclass>

    </class>
</hibernate-mapping>

```

But for now, I’ve found this solution by manually intervening on the metadata.

 ![image](https://canada1.discourse-cdn.com/flex035/uploads/hibernate/original/2X/d/d3dbc9f54dc6855e61c015c312d4b6d31c5d661e.png)

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [January 23, 2024, 4:09pm UTC](https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889/4 "2024-01-23T16:09:18Z")

</div>

You can alter some static variable i.e. `static boolean called;` in your listener and check that the flag was set in an assertion to verify that a listener was called.

---

<div class="post-metadata">

**Author:** ![boutss](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/boutss/32/1543_2.png) [@boutss](https://discourse.hibernate.org/u/boutss)\
**Post date:** [January 23, 2024, 4:45pm UTC](https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889/5 "2024-01-23T16:45:36Z")

</div>

But I mean I have no XML tag to pass the listener in question.  
It’s as if `@EntityListeners` doesn’t exist for annotation-based mapping.

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [January 23, 2024, 5:30pm UTC](https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889/6 "2024-01-23T17:30:37Z")

</div>

You can specify the listener in a JPA orm.xml: [Hibernate ORM User Guide](https://docs.jboss.org/hibernate/orm/6.4/userguide/html_single/Hibernate_User_Guide.html#bootstrap-jpa-xml-files)  
This is the `<entity-mappings/>` file you have posted a picture of.

---

<div class="post-metadata">

**Author:** ![boutss](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/boutss/32/1543_2.png) [@boutss](https://discourse.hibernate.org/u/boutss)\
**Post date:** [January 23, 2024, 5:56pm UTC](https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889/7 "2024-01-23T17:56:52Z")

</div>

Ah, indeed, sorry. I was still focused on the HMB file.  
I’ll do that as soon as possible. Thank you.

---

<div class="post-metadata">

**Author:** ![boutss](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/boutss/32/1543_2.png) [@boutss](https://discourse.hibernate.org/u/boutss)\
**Post date:** [January 24, 2024, 8:30am UTC](https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889/8 "2024-01-24T08:30:49Z")

</div>

Note that for configuration via XML file, it would be possible to specify default listeners for all entities (which I will test), and it’s not possible to define a specific one for a particular entity.

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [January 24, 2024, 2:00pm UTC](https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889/9 "2024-01-24T14:00:44Z")

</div>

With hbm.xml it’s not possible, but with pure orm.xml you can define a listener per entity/mapped-superclass. Who knows, maybe it even works in combination with hbm.xml. I haven’t tried though.

---

<div class="post-metadata">

**Author:** ![boutss](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/boutss/32/1543_2.png) [@boutss](https://discourse.hibernate.org/u/boutss)\
**Post date:** [January 25, 2024, 10:04am UTC](https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889/10 "2024-01-25T10:04:41Z")

</div>

I just noticed that the use of `<hibernate-mapping>` is deprecated (`hbm.xml`).  
It suggests using `orm.xml` or `mapping.xml` or enable `hibernate.transform_hbm_xml`.  
Which do you think is better to use?

> 10:58:33,447|WARN |{}|orm.deprecation|main|HHH90000028: Support for `<hibernate-mappings/>` is deprecated [INPUT\_STREAM : D:\java\workspaces\developpement\_dev\efluid\app\target\classes\com\hermes\ref\acteur\businessobject\ActeurInterne.hbm.xml]; migrate to orm.xml or mapping.xml, or enable `hibernate.transform_hbm_xml.enabled` for on the fly transformation

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [January 25, 2024, 11:25am UTC](https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889/11 "2024-01-25T11:25:04Z")

</div>

The best way IMO is to use annotations, but if you must use XML, you should use orm.xml since hbm.xml will probably be removed in ORM 7, which will be released later this year.

---

<div class="post-metadata">

**Author:** ![boutss](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/boutss/32/1543_2.png) [@boutss](https://discourse.hibernate.org/u/boutss)\
**Post date:** [January 25, 2024, 1:37pm UTC](https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889/12 "2024-01-25T13:37:21Z")

</div>

I just understood:

- hbm.xml is a separate complete definition from the mapping but it will disappear
- orm.xml is simply the completion of annotations by text file

In my case, the issue is that I want to avoid keeping an inheritance from a problematic parent class, so I am forced to use hbm.xml.

It’s worth noting that this is temporary, just while we make the necessary changes to the incorrect model. This will resolve the situation for the next 6 to 8 months.

![image](https://canada1.discourse-cdn.com/flex035/uploads/hibernate/original/2X/f/fff2b733eb3acacb7e87ed1abe134840d4788a8a.png)

---

<div class="post-metadata">

**Author:** ![boutss](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/boutss/32/1543_2.png) [@boutss](https://discourse.hibernate.org/u/boutss)\
**Post date:** [January 25, 2024, 1:48pm UTC](https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889/13 "2024-01-25T13:48:02Z")

</div>

My specific case

 ![image](https://canada1.discourse-cdn.com/flex035/uploads/hibernate/original/2X/c/c0a00719ab3485b4c1f9f303df3b52314dfc4e19.png)

---

<div class="post-metadata">

**Author:** ![boutss](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/boutss/32/1543_2.png) [@boutss](https://discourse.hibernate.org/u/boutss)\
**Post date:** [January 29, 2024, 8:45am UTC](https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889/14 "2024-01-29T08:45:59Z")

</div>

Given that HMB is going to be deprecated, is it worth it for me to create a reproduction test and a JIRA ticket?

---

<div class="post-metadata">

**Author:** ![beikov](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/beikov/32/258_2.png) [@beikov](https://discourse.hibernate.org/u/beikov)\
**Post date:** [January 29, 2024, 10:24am UTC](https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889/15 "2024-01-29T10:24:55Z")

</div>

Probably not. You should rather try to port this over to orm.xml or annotations.

---

<div class="post-metadata">

**Author:** ![boutss](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/boutss/32/1543_2.png) [@boutss](https://discourse.hibernate.org/u/boutss)\
**Post date:** [March 5, 2026, 2:26pm UTC](https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889/16 "2026-03-05T14:26:57Z")

</div>

I know that **HBM.xml** files are going to disappear, but I had adopted this solution to create callbacks on the `PersistentClass`.

I just migrated it when upgrading to **7.2.5**.

I’m a bit surprised to see that they are still present, which—honestly—works in my favor, since it gives us a bit more time to migrate the concepts that are problematic for us.

It also allows me to record it as well. 😄

```java
package com.efluid.hibernate.core.sessionfactory;

import org.hibernate.boot.ResourceStreamLocator;
import org.hibernate.boot.spi.AdditionalMappingContributions;
import org.hibernate.boot.spi.AdditionalMappingContributor;
import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.jpa.event.internal.CallbackDefinitionResolver;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.models.spi.ClassDetails;
import org.hibernate.models.spi.ClassDetailsRegistry;

import com.hermes.arc.commun.businessobject.HermesBusinessObject;

/**
 * Résout le problème de ne pas pouvoir transmettre de callback (listener) via HBM (fichier xml).
 * Voir https://discourse.hibernate.org/t/unable-to-pass-the-listeners-callback-to-hbm/8889/1
 * <p>
 * Intervient pendant la phase de build des métadonnées, au moment où InFlightMetadataCollector
 * est encore vivant — ce qui permet d'appeler resolveLifecycleCallbacks qui en a besoin.
 * <p>
 * Parcourt toutes les PersistentClass mappant une classe héritant de HermesBusinessObject
 * et sans callback, puis les résout comme le ferait @PrePersist / @PostXxx via annotations.
 */
public class EfluidCallbackHbmContributor implements AdditionalMappingContributor {

  @Override
  public String getContributorName() {
    return "EfluidCallbackHbmContributor";
  }

  @Override
  public void contribute(
      AdditionalMappingContributions contributions,
      InFlightMetadataCollector metadata,
      ResourceStreamLocator resourceStreamLocator,
      MetadataBuildingContext buildingContext) {

    ClassDetailsRegistry registry = metadata.getClassDetailsRegistry();

    metadata.getEntityBindings().stream()
            .filter(this::isPersistentClassSansCallback)
            .forEach(persistentClass -> {
              ClassDetails classDetails = registry.getClassDetails(persistentClass.getMappedClass().getName());
              CallbackDefinitionResolver.resolveLifecycleCallbacks(classDetails, persistentClass, metadata);
            });
  }

  private boolean isPersistentClassSansCallback(PersistentClass persistentClass) {
    return persistentClass.getCallbackDefinitions().isEmpty() && HermesBusinessObject.class.isAssignableFrom(persistentClass.getMappedClass());
  }
}

```
