25

In Hibernate 4.3.x, there is a method getClassMapping(className) of class org.hibernate.cfg.Configuration. But in Hibernate 5.x, this getClassMapping(className) method is removed from Configuration class.

What will be the code substitution in Hibernate-5?

Please help on this migration issue.

flo
  • 9,713
  • 6
  • 25
  • 41
Nirav Patel
  • 1,304
  • 2
  • 13
  • 30
  • Do you need it while bootstrapping or at runtime? – flo Oct 13 '15 at 07:33
  • No, I have implemented custom caching mechanism. So I need it after bootstrapping when queries are fired. Link [http://docs.jboss.org/hibernate/orm/5.0/userGuide/en-US/html_single/#bootstrap](http://docs.jboss.org/hibernate/orm/5.0/userGuide/en-US/html_single/#bootstrap) is helpful if I need to retrieve or build metadata or sessionFactory. But steps after bootstrapping is not given in documentation. – Nirav Patel Oct 15 '15 at 07:01
  • `ClassMetadata` isn't enough? You can get it from `SessionFactory` via `ClassMetadata getClassMetadata(String entityName)`. – flo Oct 15 '15 at 10:04
  • No `ClassMetadata` is not enough. Need `PersistentClass` from metadata. – Nirav Patel Oct 16 '15 at 05:37

4 Answers4

6

I posted to Broadleaf Commerce because they also needed PersistentClass:

I've been tooling with Hibernate 5, and some of these changes .... To get metadata now use the Serviceloader:

package org.broadleafcommerce.openadmin.server.dao;

import org.hibernate.boot.SessionFactoryBuilder;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.boot.spi.SessionFactoryBuilderFactory;
import org.hibernate.boot.spi.SessionFactoryBuilderImplementor;

public class EntityMetaData implements SessionFactoryBuilderFactory {

    private static final ThreadLocal<MetadataImplementor> meta = new ThreadLocal<>();

    @Override
    public SessionFactoryBuilder getSessionFactoryBuilder(MetadataImplementor metadata, SessionFactoryBuilderImplementor defaultBuilder) {
        meta.set(metadata);
        return defaultBuilder;
    }

    public static MetadataImplementor getMeta() {
        return meta.get();
    }
}

You will need the file:

/resources/META-INF/services/org.hibernate.boot.spi.SessionFactoryBuilderFactory

with the fully qualified class name, which in my example is:

org.broadleafcommerce.openadmin.server.dao.EntityMetaData
approxiblue
  • 6,982
  • 16
  • 51
  • 59
John
  • 315
  • 2
  • 7
  • Thanks, above solution worked. I made only one change in EntityMetaData class i.e., instead of using ThreadLocal, I used HashMap to store metadata object. – Nirav Patel Oct 20 '15 at 03:20
  • 1
    How is the getSessiongFactoryBuilder method getting executed? So that I can call getMeta() to get the MetadataImplementor. Is EntityMetaData to be injected into Hibernate in some way? Sorry don't understand... – Vering Apr 26 '17 at 11:42
  • @NiravPatel@John Can you please share the complete solution for this problem as I am unable to implement. – rxt66 Dec 10 '20 at 06:37
  • I did exactly that and even though I debugged it and made sure that this class is actually gets called, when I call EntityMetaData.get() it returns null, why??. Also when I replace ThreadLocal meta with just MetadataImplementor and directly assign it it works. – Hamza Assada Dec 04 '21 at 21:50
2

Get an object of PersisterCreationContext and then try this :-

PersistentClass persistentClass = 
persisterCreationContext.getMetadata().getEntityBinding(className);

Pls check this link (Example 3.8. Native Bootstrapping - Putting it all together) to understand how to get standardRegistry, metadata and sessionFactory in Hibernate 5.x

Now as we were pulling metadata from persisterCreationContext and now we already had it so we can right away get the required PersistentClass object of any entity by

SessionFactory sessionFactory = metadata.getSessionFactoryBuilder().build();
PersistentClass persistentClass = metadata.getEntityBinding(className);
Avis
  • 2,197
  • 18
  • 28
  • How to retrieve persisterCreationContext? Can you please update answer with proper steps. i.e., normally we`ll have sessionFactory object or configuration object, so how can we retrieve PersisterCreationContext from it? – Nirav Patel Oct 13 '15 at 09:15
  • I need reverse of what is suggested in link. Is there any way to retrieve metadata from org.springframework.orm.hibernate5.LocalSessionFactoryBean or org.hibernate.SessionFactory object? – Nirav Patel Oct 14 '15 at 13:26
  • As in hibernate-4.x, getClassMapping(className) method is in Configuration class. So i`m having configuration object only. As now in hibernte-5.x this method is removed from class, I need to retrieve metadata or persisterCreationContext from configuration object. – Nirav Patel Oct 15 '15 at 04:55
  • I could think about one solution is if you write an ASPECT around the constructor of class org.hibernate.internal.SessionFactoryImpl. So as soon it gets invoked while system gets loaded you can get handle of the metaData for your task. Constructor is :- public SessionFactoryImpl(final MetadataImplementor metadata, SessionFactoryOptions options) {} – Avis Oct 15 '15 at 11:49
  • Is it possible to retrieve constructor param and store it in custom class bean using Aspect Oriented Programming? – Nirav Patel Oct 16 '15 at 11:25
2

In Hibernate 3 and 4 you would do something like this

URL configFileURL = getResource(); //some method to get hold of the location of your hibernate.cfg.xml
Configuration configuration = (new Configuration()).configure(configFileURL);
Iterator classMappings = configuration.getClassMappings();
  while (classMappings.hasNext()) {
    PersistentClass persistentClass = (PersistentClass) classMappings.next();
    //do somthing 
    }

In Hibernate 5 initialise Metadata like this

URL configFileURL = getResource(); //some method to get hold of the location of your hibernate.cfg.xml
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder().configure(configFileURL).build();
Metadata metaData = new MetadataSources(standardRegistry).getMetadataBuilder().build();

And use getEntityBindings() on metadata

Collection<PersistentClass> entityBindings = metadata.getEntityBindings();
Iterator<PersistentClass> iterator = entityBindings.iterator();
  while (iterator.hasNext()) {
    PersistentClass persistentClass = iterator.next();    
    //do somthing
  }
Vering
  • 907
  • 9
  • 19
0

This is discussed in the Hibernate 5.0 Migration Guide as well as the Bootstrap chapter in the Hibernate User Guide (see especially the "Legacy Bootstrapping" appendix).

In short, while Configuration is still supported for straight-line bootstrapping, if you want to "hook into" the bootstrap process you are going to have to use the new bootstrap APIs.

Steve Ebersole
  • 9,339
  • 2
  • 48
  • 46
  • Bootstrapping links are broken, and Migration Guide link currently points to an empty 5.4 migration document. – Greg Brown Aug 22 '18 at 14:25