0

I am trying to upgrade my hibernate version from 3 to 5.0.

Can you please advise how to get ObjectNameNormalizer in hibernate 5. My current code is still using Configuration to retrieve session factory which I can't change as we are setting properties on the fly in code.

Below code needs to be re-written in hibernate 5 -

Mappings mappings = c.createMappings(); (this method does not exist in 5.0)

props.put(TableGenerator.IDENTIFIER_NORMALIZER, mappings.getObjectNameNormalizer());
Prasanth Rajendran
  • 4,570
  • 2
  • 42
  • 59
Alps
  • 1
  • 3

2 Answers2

0

Try this solution. We faced the same problem.

package test.hibernate.generator;

import java.io.Serializable;
import java.util.Properties;

import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.boot.model.naming.ObjectNameNormalizer;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.id.Configurable;
import org.hibernate.id.IdentityGenerator;
import org.hibernate.id.enhanced.TableGenerator;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.testing.boot.MetadataBuildingContextTestingImpl;
import org.hibernate.type.LongType;
import org.hibernate.type.Type;

import hu.gov.nebih.cdv.CdvHelper;
import hu.gov.nebih.domain.entity.BaseEntity;

public class CustomIdGenerator extends IdentityGenerator implements Configurable {
    private CustomTableGenerator tableGenerator = new CustomTableGenerator();
    private ServiceRegistry serviceRegistry;

    @Override
    public Serializable generate(SessionImplementor session, Object obj) throws HibernateException {
        if (obj == null)
            throw new HibernateException(new NullPointerException());

        if (isIdNull(obj)) {
            return generateCustomId(session, obj);
        } else {
            return getUsedId(obj);
        }
    }

    private boolean isIdNull(Object obj) {
        return (obj instanceof BaseEntity && ((BaseEntity) obj).getId() == null);
    }

    private Serializable getUsedId(Object obj) {
        if (obj instanceof BaseEntity) {
            return ((BaseEntity) obj).getId();
        }
        return null;
    }

    private synchronized Serializable generateCustomId(SessionImplementor session, Object obj) {
        configureTableGenerator(session, tableGenerator);

        Long nextVal = (Long) tableGenerator.generate(session, obj);

        if (nextVal != null) {
            //any operation
        }

        return nextVal;
    }

    private CustomTableGenerator configureTableGenerator(SessionImplementor session, CustomTableGenerator tg) {
        if (tg.isConfigured()) {
            return tg;
        }

        final MetadataBuildingContext context = new MetadataBuildingContextTestingImpl((StandardServiceRegistry) serviceRegistry);

        ObjectNameNormalizer normalizer = new ObjectNameNormalizer() {
            @Override
            protected MetadataBuildingContext getBuildingContext() {
                return context;
            }
        };

        Properties params = new Properties();
        params.put(TableGenerator.TABLE_PARAM, "custom_sequence");
        params.put(TableGenerator.VALUE_COLUMN_PARAM, "next_val");
        params.put(TableGenerator.INITIAL_PARAM, 7000000);
        params.put(TableGenerator.INCREMENT_PARAM, 1);
        params.put(TableGenerator.IDENTIFIER_NORMALIZER, normalizer);
        params.put(TableGenerator.SEGMENT_COLUMN_PARAM, "sequence_name");
        params.put(TableGenerator.SEGMENT_VALUE_PARAM, "value_param");

        tg.configure(new LongType(), params, session.getFactory().getServiceRegistry());
        tg.registerExportables(context.getMetadataCollector().getDatabase());
        tg.setConfigured(true);

        return tg;
    }

    @Override
    public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
        this.serviceRegistry = serviceRegistry;
    }

    class CustomTableGenerator extends TableGenerator {
        private boolean configured = false;

        public boolean isConfigured() {
            return configured;
        }

        public void setConfigured(boolean configured) {
            this.configured = configured;
        }
    }
}
0

Most of the existing answers in online to get ObjectNameNormalizer instance are using MetadataBuildingContextTestingImpl to get MetadataBuildingContext. Actually, MetadataBuildingContextTestingImpl class belongs to 'org.hibernate:hibernate-testing' dependency. The test scope hibernate-testing dependency is not a candidate for the runtime classpath. Hence, added the below working solution to instantiate ObjectNameNormalizer which requires only 'org.hibernate:hibernate-core' in your classpath

        props.put(PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER, new ObjectNameNormalizer() {

            
            @Override
            protected MetadataBuildingContext getBuildingContext() {
                StandardServiceRegistry serviceRegistry = sessionFactory.getSessionFactoryOptions().getServiceRegistry();
                MetadataBuildingOptions buildingOptions = new MetadataBuilderImpl.MetadataBuildingOptionsImpl(serviceRegistry);
                BootstrapContext bootstrapContext = new BootstrapContextImpl( serviceRegistry, buildingOptions );
                InFlightMetadataCollector metadataCollector = new InFlightMetadataCollectorImpl( bootstrapContext, buildingOptions );
                return new MetadataBuildingContextRootImpl(bootstrapContext, buildingOptions, metadataCollector);
            }
        });
Prasanth Rajendran
  • 4,570
  • 2
  • 42
  • 59