admin管理员组

文章数量:1291676

I have a table my_entity that is referenced by multiple @Entity annotated classes like so:

@Immutable
@Entity
@Table(name = "my_entity")
public class EntityA { ... }
@Entity
@Table(name = "my_entity")
public class EntityB { ... }

This works perfectly fine.

I now have to change one of these entities to extend an @Inheritance annotated class to allow for polymorphic queries:

@Immutable
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Parent { ... }
@Immutable
@Entity
@Table(name = "my_entity")
public class EntityA extends Parent { ... }
@Entity
@Table(name = "my_entity")
public class EntityB { ... }

I then get a .hibernate.DuplicateMappingException: Duplicate table my_entity

Caused by: .springframework.beans.factory.BeanCreationException: Error creating bean with name '.springframework.orm.jpa.SharedEntityManagerCreator#0': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is .springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is .hibernate.DuplicateMappingException: Duplicate table mapping my_entity
    at app//.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:342)
    at app//.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:113)
    at app//.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:688)
    at app//.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:505)
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at app//.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at app//.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at app//.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at app//.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at app//.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
    at app//.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391)
    at app//.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311)
    at app//.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:911)
    at app//.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:788)
    ... 193 more
Caused by: .springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is .hibernate.DuplicateMappingException: Duplicate table mapping my_entity
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804)
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at app//.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at app//.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at app//.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at app//.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at app//.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:330)
    ... 209 more
Caused by: .hibernate.DuplicateMappingException: Duplicate table mapping my_entity
    at app//.hibernate.boot.internal.InFlightMetadataCollectorImpl.addDenormalizedTable(InFlightMetadataCollectorImpl.java:799)
    at app//.hibernate.cfg.annotations.TableBinder.buildAndFillTable(TableBinder.java:488)
    at app//.hibernate.cfg.annotations.EntityBinder.bindTable(EntityBinder.java:849)
    at app//.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:642)
    at app//.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:225)
    at app//.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.java:239)
    at app//.hibernate.boot.model.process.spi.MetadataBuildingProcessplete(MetadataBuildingProcess.java:282)
    at app//.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1460)
    at app//.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1494)
    at app//.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
    at app//.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
    at app//.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
    at app//.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
    at app//.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
    ... 216 more

Is there a way to still reference the same table in an inheritance hierarchy?

My workaround would be to create a view based on the my_entity table and use this for the mapping of EntityA, but I would prefer a solution based on the entity definition if there exists one.

I also don't understand why using @Inheritance would create this issue while it was working fine before.

I'm using Hibernate 5.6.15.

I have a table my_entity that is referenced by multiple @Entity annotated classes like so:

@Immutable
@Entity
@Table(name = "my_entity")
public class EntityA { ... }
@Entity
@Table(name = "my_entity")
public class EntityB { ... }

This works perfectly fine.

I now have to change one of these entities to extend an @Inheritance annotated class to allow for polymorphic queries:

@Immutable
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Parent { ... }
@Immutable
@Entity
@Table(name = "my_entity")
public class EntityA extends Parent { ... }
@Entity
@Table(name = "my_entity")
public class EntityB { ... }

I then get a .hibernate.DuplicateMappingException: Duplicate table my_entity

Caused by: .springframework.beans.factory.BeanCreationException: Error creating bean with name '.springframework.orm.jpa.SharedEntityManagerCreator#0': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is .springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is .hibernate.DuplicateMappingException: Duplicate table mapping my_entity
    at app//.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:342)
    at app//.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:113)
    at app//.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:688)
    at app//.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:505)
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at app//.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at app//.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at app//.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at app//.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at app//.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
    at app//.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391)
    at app//.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311)
    at app//.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:911)
    at app//.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:788)
    ... 193 more
Caused by: .springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is .hibernate.DuplicateMappingException: Duplicate table mapping my_entity
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804)
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at app//.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at app//.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at app//.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at app//.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at app//.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:330)
    ... 209 more
Caused by: .hibernate.DuplicateMappingException: Duplicate table mapping my_entity
    at app//.hibernate.boot.internal.InFlightMetadataCollectorImpl.addDenormalizedTable(InFlightMetadataCollectorImpl.java:799)
    at app//.hibernate.cfg.annotations.TableBinder.buildAndFillTable(TableBinder.java:488)
    at app//.hibernate.cfg.annotations.EntityBinder.bindTable(EntityBinder.java:849)
    at app//.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:642)
    at app//.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:225)
    at app//.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.java:239)
    at app//.hibernate.boot.model.process.spi.MetadataBuildingProcessplete(MetadataBuildingProcess.java:282)
    at app//.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1460)
    at app//.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1494)
    at app//.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
    at app//.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
    at app//.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
    at app//.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
    at app//.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
    at app//.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
    ... 216 more

Is there a way to still reference the same table in an inheritance hierarchy?

My workaround would be to create a view based on the my_entity table and use this for the mapping of EntityA, but I would prefer a solution based on the entity definition if there exists one.

I also don't understand why using @Inheritance would create this issue while it was working fine before.

I'm using Hibernate 5.6.15.

Share Improve this question edited Feb 17 at 10:59 flauschtrud asked Feb 13 at 13:23 flauschtrudflauschtrud 9209 silver badges24 bronze badges 7
  • @Gimby JPA inheritance is on entities, so the parent should be an entity. – Chris Commented Feb 13 at 20:09
  • Why do you have two classes to the same table at all? There is no requirement to have one entity per table, so I don't know why Hibernate isn't allowing it, but it does have drawbacks around caching; EntityA and EntityB representing the same row are cached independently, so won't show changes automatically without being refreshed. For the error - maybe show the exception stack trace as there might be setting to turn off that validation check. – Chris Commented Feb 13 at 20:10
  • Where is exception is thrown? Please add top of stack trace. – talex Commented Feb 14 at 6:48
  • @Chris right, it's been a while since I've used it. Having the strategy TABLE_PER_CLASS isn't exactly logical then if the goal is to ... have one table. The strategy with a discriminator column should be used instead. – Gimby Commented Feb 14 at 8:34
  • @talex I added the stacktrace for the exception. It occurs when the EntityManager is injected in one of my other classes. – flauschtrud Commented Feb 17 at 11:01
 |  Show 2 more comments

1 Answer 1

Reset to default 1
  • it is a problem in hibernate https://hibernate.atlassian/browse/HHH-8277

in InFlightMetadataCollectorImpl.addDenormalizedTable we have the following

...
if ( subselectFragment != null ) {
        return new DenormalizedTable( namespace, logicalName, subselectFragment, isAbstract, includedTable );
    }
    else {
        Table table = namespace.locateTable( logicalName );
        if ( table != null ) {
            throw new DuplicateMappingException( DuplicateMappingException.Type.TABLE, logicalName.toString() );
        }
        else {
            table = namespace.createDenormalizedTable( logicalName, isAbstract, includedTable );
        }
        return table;
    }
  • the exception is raised at line 799 that is throw new DuplicateMappingException
  • like the https://hibernate.atlassian/browse/HHH-8277 says, the problem is there only when the simple entity is loaded before the complex entity; the problem is gone when the complex entity is loaded after the simple entity.
  • the order in which the entities are loaded seems to be the same order the associated java classes are added in the jar

possible general solutions

  • check if this is ongoing in hibernate 6, probably yes
  • create a pull request with a fix in hibernate 5 (could be complex unless instructed by hibernate gurus on what the solution could be)

possible personal solutions

  • if there is a way to determine the order in which java classes are added in a jar you could influence it and make the complex entity class be added in the jar before the simple entity class
  • otherwise at runtime update the order of the entries in the PersistenceUnitInfo.getManagedClassNames collection so that the className associated to the complex entity comes before the className associated to the simple entity

本文标签: javaDuplicateMappingException after extending Entity with InheritanceStack Overflow