# Hibernate 5 - programmatically adding HBM mapping to the configuration - no named queries found

**URL:** <https://discourse.hibernate.org/t/hibernate-5-programmatically-adding-hbm-mapping-to-the-configuration-no-named-queries-found/948>\
**Category:** Hibernate ORM\
**Created:** [June 20, 2018, 2:01pm UTC](https://discourse.hibernate.org/t/hibernate-5-programmatically-adding-hbm-mapping-to-the-configuration-no-named-queries-found/948 "2018-06-20T14:01:57Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sergiu](https://avatars.discourse-cdn.com/v4/letter/s/b487fb/32.png) [@Sergiu](https://discourse.hibernate.org/u/Sergiu)\
**Post date:** [June 20, 2018, 2:01pm UTC](https://discourse.hibernate.org/t/hibernate-5-programmatically-adding-hbm-mapping-to-the-configuration-no-named-queries-found/948/1 "2018-06-20T14:01:57Z")

</div>

In the process of migrating an old app from JBoss 5.1.0GA to WildFly 13.  
On the previous server we were using hibernate3 while on WildFly 13 we’re trying to use hibernate 5.

A bit on the app - it’s built as a multi-tenant app so it has tables that are common to all the clients and tables that are client specific. These client specific tables are suffixed with the clientId, so they would read Document\_2, Document\_3, …, Document\_n (e.g.).

The common tables definitions are in a .sar archive, under the hibernate.cfg.xml file.

For the common table mappings there is another class like so:

```
> @Singleton

```

> ```
> @Startup
> public class MyHibernateService
> implements
> DynamicMBean {
> 
> private MBeanServer platformMBeanServer;
> private ObjectName objectName = null;
> 
> @PostConstruct
> public void start() {
> new Configuration().configure().buildSessionFactory();
> this.registerJMX();
> }
> 
> private void registerJMX() {
> try {
> this.objectName = new ObjectName("jboss.jca:service=HibernateFactory,name=HibernateFactory");
> this.platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
> this.platformMBeanServer.registerMBean(this, this.objectName);
> } catch (Exception e) {
> throw new IllegalStateException("Exception during JMX registration :" + e);
> }
> }
> ....
> }
> 
> ```

This class binds the hibernate factory for the common tables under a JNDI name so it can be retrieved later.

The client specific tables definitions / mapping are derived from a template. On app boot we build session factories specific for each client. The way we do this is that we parse the template mapping and replace some sections with the client specific one. The template would read

> 

where TABLENAME that would get replace at boot with e.g. Document\_2.

This SessionFactoryManager class that does all the replacement looks like below:

```
> if (SessionFactoryManager.LOGGER.isDebugEnabled()) {

```

> ```
> SessionFactoryManager.LOGGER.info("build custom SessionFactory for datasource: " + databaseConfig);
> }
> 
> Configuration cfg = new Configuration();
> 
> // build all mappings
> for (Class c : mappingClasses) {
> 
> try {
> Method m = c.getMethod("getInstance", (Class[])null);
> Helper dao = (Helper)m.invoke(null, (Object[])null);
> 
> String tableName = dao.getTableName(id);
> 
> String mapping = dao.getMappping();
> 
> if (mapping == null) {
> throw new DAOException(DAOException.TYPE.SESSION_FACTORY, "Mapping not available from class: " + c.getName());
> }
> 
> 	
> cfg.addXML(mapping);
> } catch (Exception e) {
> throw new DAOException(DAOException.TYPE.SESSION_FACTORY, e);
> }
> }
> 
> cfg.setProperty("hibernate.dialect", databaseConfig.getDatabaseDialect().getClass().getName());
> 
> if (StringTools.isValidString(databaseConfig.getDatabaseJNDI())) {
> cfg.setProperty("hibernate.connection.datasource", databaseConfig.getDatabaseJNDI());
> } else {
> cfg.setProperty("hibernate.connection.url", databaseConfig.getDatabaseURL());
> cfg.setProperty("hibernate.connection.driver_class", databaseConfig.getDatabaseDriverClass());
> cfg.setProperty("hibernate.connection.username", databaseConfig.getDatabaseUser());
> cfg.setProperty("hibernate.connection.password", databaseConfig.getDatabasePassword());
> }
> 
> if (showSQL) {
> cfg.setProperty("hibernate.show_sql", "true");
> cfg.setProperty("hibernate.format_sql", "false");
> }
> 
> if (operation == OPERATION.RECREATE) {
> cfg.setProperty("hibernate.hbm2ddl.auto", "update");
> } else {
> // With create-drop, the database schema will be dropped when the SessionFactory is closed explicitly
> // this is necessary in order to remove client tables if something goes wrong at client creation time
> cfg.setProperty("hibernate.hbm2ddl.auto", "create-drop");
> }
> 
> SessionFactory sf = cfg.configure().buildSessionFactory();
> 
> System.out.println(cfg.getNamedQueries());
> 
> ```

The problem is that, although I see that cfg.addXML(String xml) is deprecated, the cfg.getNamedQueries() returns an empty map, as if the mapping is not loaded onto the configuration.

All the above code works fine for hibernate3.

I also tried changing:

> SessionFactory sf = cfg.configure().buildSessionFactory();

to

```
> StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder();

```

> ```
> builder.applySettings(cfg.getProperties());
> MetadataSources metaData = new MetadataSources(builder.build());
> Metadata buildMetadata = metaData.buildMetadata(builder.build());
> SessionFactory sf = buildMetadata.buildSessionFactory();
> 
> ```

but to no avail.

Any ideas ?

---

<div class="post-metadata">

**Author:** ![vlad](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/vlad/32/658_2.png) [@vlad](https://discourse.hibernate.org/u/vlad)\
**Post date:** [June 20, 2018, 2:12pm UTC](https://discourse.hibernate.org/t/hibernate-5-programmatically-adding-hbm-mapping-to-the-configuration-no-named-queries-found/948/2 "2018-06-20T14:12:02Z")

</div>

Do it like this for HBM:

```auto
String mapping = dao.getMappping();

if (mapping == null) {
	throw new DAOException(DAOException.TYPE.SESSION_FACTORY, "Mapping not available from class: " + c.getName());
}

configuration.addResource(
	mapping,
	getClass().getClassLoader()
);

```

or for JPA mappings files:

```auto
String mapping = dao.getMappping();

if (mapping == null) {
	throw new DAOException(DAOException.TYPE.SESSION_FACTORY, "Mapping not available from class: " + c.getName());
}

try (InputStream is = Thread.currentThread().getContextClassLoader()
		.getResourceAsStream( xmlFile )) {
	configuration.addInputStream( is );
}
catch (IOException e) {
	throw new IllegalArgumentException( e );
}

```

---

<div class="post-metadata">

**Author:** ![Sergiu](https://avatars.discourse-cdn.com/v4/letter/s/b487fb/32.png) [@Sergiu](https://discourse.hibernate.org/u/Sergiu)\
**Post date:** [June 21, 2018, 5:47am UTC](https://discourse.hibernate.org/t/hibernate-5-programmatically-adding-hbm-mapping-to-the-configuration-no-named-queries-found/948/3 "2018-06-21T05:47:48Z")

</div>

Changing

> cfg.addXML(mapping);

to

> cfg.addResource(mapping, SessionFactoryManager.class.getClassLoader());

leads to a mapping not found exception:

> org.hibernate.boot.MappingNotFoundException: Mapping (RESOURCE) not found : \<?xml version=\"1.0\"?\>

…

This is correct, in some sorts, because that actual mapping file does not exist under my classpath since it’s derived from the template. What I’m trying to achieve is to dynamically add the “derived” mapping to the configuration.

To recap: every tenant of the app has an id. Every tenant has its own tables - suffixed with their id. The goal would be to create a sesion factory for every client, starting from a series of mapping templates.  
Each mapping template has values replaced, at app boot, so as to create dynamic mappings that conform to every tenants’ tables.

The mapping template would read (e.g.):

```
<class name="com.test.Document" table="TABLENAME">

```

…

At app boot the “TABLENAME” would get replace with Document\_“tenantId” and then there would be a string holding the XML mapping. What I would like to do (and this was possible in hibernate3) would be to dynamically add this “string” mapping to the configuration, without actually having the specific mapping in the app EAR.

Code-wise, this would look like so:

> for (Class c : mappingClasses) {  
> // iterating over all the classes that are client specific  
> try {  
> Method m = c.getMethod(“getInstance”, (Class)null);  
> DAOHelper dao = (DAOHelper)m.invoke(null, (Object)null);
> 
> String tableName = dao.getTableName(id);
> 
> ```
> // getting the template mapping associated with the respective class/table
> 
> ```
> 
> String mapping = dao.getMappping();
> 
> if (mapping == null) {  
> throw new DAOException(DAOException.TYPE.SESSION\_FACTORY, "Mapping not available from class: " + c.getName());  
> }
> 
> ```
> // replacing some keywords in the template (such as TABLENAME) with specific tenant values
> mapping = mapping.replace(TABLE_NAME_KEY, tableName).replace(SEQUENCE_NAME_KEY,
> dao.getSequenceName(databaseConfig.getDatabaseDialect(), tableName));
> 
> // at this point the mapping is changed from the "template" form to the "client" form
> // dynamically adding the new mapping (client form) to the configuration
> cfg.addXML(mapping);
> 
> ```
> 
> }

Hope the above sheds some more light on my situation.

Thanks !

---

<div class="post-metadata">

**Author:** ![Sergiu](https://avatars.discourse-cdn.com/v4/letter/s/b487fb/32.png) [@Sergiu](https://discourse.hibernate.org/u/Sergiu)\
**Post date:** [June 21, 2018, 6:14am UTC](https://discourse.hibernate.org/t/hibernate-5-programmatically-adding-hbm-mapping-to-the-configuration-no-named-queries-found/948/4 "2018-06-21T06:14:25Z")

</div>

Fixed it by changing

> cfg.addXml(String xml)

to

> cfg.addInputStream(new ByteArrayInputStream(mapping.getBytes()));

---

<div class="post-metadata">

**Author:** ![vlad](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/vlad/32/658_2.png) [@vlad](https://discourse.hibernate.org/u/vlad)\
**Post date:** [June 21, 2018, 6:31am UTC](https://discourse.hibernate.org/t/hibernate-5-programmatically-adding-hbm-mapping-to-the-configuration-no-named-queries-found/948/5 "2018-06-21T06:31:52Z")

</div>

The `mapping` can be:

- a URL String representation (e.g. file://…, classpatch://…)

- the full path to of the resource inside the jar, like this:

I suppose the `mapping` was just `A.hbm.xml` in your case.

---

<div class="post-metadata">

**Author:** ![Sergiu](https://avatars.discourse-cdn.com/v4/letter/s/b487fb/32.png) [@Sergiu](https://discourse.hibernate.org/u/Sergiu)\
**Post date:** [June 21, 2018, 6:45am UTC](https://discourse.hibernate.org/t/hibernate-5-programmatically-adding-hbm-mapping-to-the-configuration-no-named-queries-found/948/6 "2018-06-21T06:45:46Z")

</div>

The template mapping, yes, was a resource inside the jar.  
The actual, derived template, was obtained by doing some replacements on the template mapping.

---

<div class="post-metadata">

**Author:** ![vlad](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/vlad/32/658_2.png) [@vlad](https://discourse.hibernate.org/u/vlad)\
**Post date:** [June 21, 2018, 8:07am UTC](https://discourse.hibernate.org/t/hibernate-5-programmatically-adding-hbm-mapping-to-the-configuration-no-named-queries-found/948/7 "2018-06-21T08:07:31Z")

</div>

As long as the resource name is properly constructed and references the mapping file in your jar, it should work.

---

<div class="post-metadata">

**Author:** ![xiaoming\_cheng](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/xiaoming_cheng/32/528_2.png) [@xiaoming\_cheng](https://discourse.hibernate.org/u/xiaoming_cheng)\
**Post date:** [November 15, 2018, 12:00pm UTC](https://discourse.hibernate.org/t/hibernate-5-programmatically-adding-hbm-mapping-to-the-configuration-no-named-queries-found/948/8 "2018-11-15T12:00:33Z")

</div>

@vlad Hello, hibernate support is dynamically created entity when runtime

---

<div class="post-metadata">

**Author:** ![vlad](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/vlad/32/658_2.png) [@vlad](https://discourse.hibernate.org/u/vlad)\
**Post date:** [November 15, 2018, 1:40pm UTC](https://discourse.hibernate.org/t/hibernate-5-programmatically-adding-hbm-mapping-to-the-configuration-no-named-queries-found/948/9 "2018-11-15T13:40:49Z")

</div>

@xiaoming_cheng Would you mind elaborating your question? I didn’t understand what you meant.

---

<div class="post-metadata">

**Author:** ![xiaoming\_cheng](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/xiaoming_cheng/32/528_2.png) [@xiaoming\_cheng](https://discourse.hibernate.org/u/xiaoming_cheng)\
**Post date:** [November 16, 2018, 12:04pm UTC](https://discourse.hibernate.org/t/hibernate-5-programmatically-adding-hbm-mapping-to-the-configuration-no-named-queries-found/948/10 "2018-11-16T12:04:05Z")

</div>

@vlad  
Similar to dynamic models  
,but what I want to achieve is to call a method to dynamically add a Domain Model after the application starts.  
at this time, the sessionFactory has been created.  
example:  
Metadata metadata = metadataBuilder.build();  
metadata.addResource( “org/hibernate/example/Product.orm.xml” ) ;

> <https://stackoverflow.com/questions/11589194/dynamically-adding-entities-to-hibernate>

---

<div class="post-metadata">

**Author:** ![vlad](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/vlad/32/658_2.png) [@vlad](https://discourse.hibernate.org/u/vlad)\
**Post date:** [November 16, 2018, 5:55pm UTC](https://discourse.hibernate.org/t/hibernate-5-programmatically-adding-hbm-mapping-to-the-configuration-no-named-queries-found/948/11 "2018-11-16T17:55:11Z")

</div>

> [@xiaoming\_cheng](#):
>
> But what I want to achieve is to call a method to dynamically add a Domain Model after the application starts.

I don’t think that’s possible. Once the `SessionFactory` is built, you can no longer register new entities. You need to stop the current `SessionFactory` and create a new one.

---

<div class="post-metadata">

**Author:** ![xiaoming\_cheng](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/xiaoming_cheng/32/528_2.png) [@xiaoming\_cheng](https://discourse.hibernate.org/u/xiaoming_cheng)\
**Post date:** [November 17, 2018, 1:14am UTC](https://discourse.hibernate.org/t/hibernate-5-programmatically-adding-hbm-mapping-to-the-configuration-no-named-queries-found/948/12 "2018-11-17T01:14:35Z")

</div>

In this case, the entities corresponding to the two sessionFactorys cannot communicate with each other.

---

<div class="post-metadata">

**Author:** ![vlad](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/vlad/32/658_2.png) [@vlad](https://discourse.hibernate.org/u/vlad)\
**Post date:** [November 17, 2018, 4:42am UTC](https://discourse.hibernate.org/t/hibernate-5-programmatically-adding-hbm-mapping-to-the-configuration-no-named-queries-found/948/13 "2018-11-17T04:42:02Z")

</div>

They don’t have to. The second SessionFactory will contain everything the first one contained plus the new entities.
