Search code examples
javamongodbhibernatehibernate-ogm

Table per class configuration with Hibernate OGM and MongoDb is not working


I am trying to have table per class configuration with Hibernate OGM + MongoDb. I have a BaseEntity like below:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class BaseEntity {
    protected UUID id;

    @Id
    // @GeneratedValue  //<--tried this only this one as well
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    public UUID getId() {
        return id;
    }

    //omitted setters and other stuffs for brevity
}

And then I have other classes which inherit from BaseEntity:

@Entity
public class OtherEntity extends BaseEntity { 
}

When I try to create the EntityManagerFactory as follows:

entityManagerFactory = Persistence.createEntityManagerFactory("persistenceUnitName");

I receive following error:

javax.persistence.PersistenceException: [PersistenceUnit: persistenceUnitName] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:954)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:882)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:58)
    at org.hibernate.ogm.jpa.HibernateOgmPersistence.createEntityManagerFactory(HibernateOgmPersistence.java:59)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
    at service.util.HibernateOgmUtil.<clinit>(HibernateOgmUtil.java:20)
    at service.data.repositories.GenericRepository.<init>(GenericRepository.java:31)
    at service.data.repositories.QuestionRepository.<init>(QuestionRepository.java:13)
    at Playground.main(Playground.java:31)
Caused by: org.hibernate.MappingException: No Dialect mapping for JDBC type: -2
    at org.hibernate.dialect.TypeNames.get(TypeNames.java:70)
    at org.hibernate.dialect.TypeNames.get(TypeNames.java:101)
    at org.hibernate.dialect.Dialect.getTypeName(Dialect.java:341)
    at org.hibernate.mapping.Column.getSqlType(Column.java:231)
    at org.hibernate.hql.spi.id.AbstractMultiTableBulkIdStrategyImpl.buildIdTableCreateStatement(AbstractMultiTableBulkIdStrategyImpl.java:144)
    at org.hibernate.hql.spi.id.persistent.PersistentTableBulkIdStrategy.buildIdTableInfo(PersistentTableBulkIdStrategy.java:130)
    at org.hibernate.hql.spi.id.persistent.PersistentTableBulkIdStrategy.buildIdTableInfo(PersistentTableBulkIdStrategy.java:43)
    at org.hibernate.hql.spi.id.AbstractMultiTableBulkIdStrategyImpl.prepare(AbstractMultiTableBulkIdStrategyImpl.java:84)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:453)
    at    org.hibernate.ogm.boot.impl.OgmSessionFactoryBuilderImpl.build(OgmSessionFactoryBuilderImpl.java:54)
    at org.hibernate.ogm.boot.impl.OgmSessionFactoryBuilderImpl.build(OgmSessionFactoryBuilderImpl.java:23)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879)
    ... 8 more

When I debugged, it seemed that the UUID can't be translated to equivalent sql type. But then, commenting the @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) made the error go away, but, it also didn't produced what I wanted.

Moreover, InheritanceType.TABLE_PER_CLASS gives warning:

Entity "BaseEntity" uses table-per-concrete-class inheritance which is not portable and may not be supported by the JPA provider

How Hibernate OGM + MongoDb can be configured effectively for table per class?


Solution

  • It will work if you use @MappedSuperClass instead.

    @MappedSuperclass
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public abstract class BaseEntity {
    
    ...
    }
    

    I will open an issue about this as we should support it or at least throw a better exception.

    Alternatively, if you can change the type of the id and you only need to use the entity with MongoDB, this will work:

    @Entity
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public abstract class BaseEntity {
       @Id
       @GeneratedValue(strategy = GenerationType.IDENTITY)    
       protected ObjectId id;
       ...
    }