简体   繁体   English

使用联接继承时无法构建Hibernate SessionFactory

[英]Unable to build Hibernate SessionFactory when using Joined inheritance

I have a class that defines an InheritanceType.JOINED from which a couple more classes inherit from: 我有一个定义InheritanceType.JOINED的类,另外两个类从该类继承:

BaseClass BaseClass的

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "DISCRIMINATOR")
@Table(name = "BASE_CLASSES", uniqueConstraints = 
@UniqueConstraint(columnNames = { "DISCRIMINATOR", "NAME" }))
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class BaseClass implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID")
protected Long id;

@Length(max = 60)
@NotNull
@Column(name = "NAME", nullable = false)
private String name;
/* Getters and setters omitted for brevity */

This class alone causes no problems when trying to run the app with Spring Boot. 尝试使用Spring Boot运行应用程序时,仅此类不会引起任何问题。 But if I add the other two classes: 但是,如果我添加其他两个类:

SubClass1 SubClass1

@Entity
@Table(name = "SUB_CLASS_1")
@DiscriminatorValue("SC1")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class SubClass1 extends BaseClass {

private static final long serialVersionUID = 1L;

@OneToMany(mappedBy = "subClass1", fetch = FetchType.LAZY)
private Set<SubClass2> subClass2s;

and

SubClass2 SubClass2

@Entity
@Table(name = "SUB_CLASS_2")
@DiscriminatorValue("SC2")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class SubClass2 extends BaseClass {

private static final long serialVersionUID = 1L;

@JoinColumn(name = "SUB_CLASS_1_ID", nullable = true)
@ManyToOne(fetch = FetchType.LAZY, optional = true)
private SubClass1 subClass1;

I get the following error: org.hibernate.AssertionFailure: Table example.BASE_CLASSES not found . 我收到以下错误: org.hibernate.AssertionFailure: Table example.BASE_CLASSES not found

The weird thing is (in the real life project I am working on) I can run my test suite (using a custom library based on Unitils) just fine but the app just won't start, with the same kind of error. 奇怪的是(在我正在研究的现实生活项目中),我可以很好地运行测试套件(使用基于Unitils的自定义库),但该应用程序无法启动,并出现相同的错误。 Because of this I think that the error might be with the way I'm configuring the entity manager factory. 因此,我认为该错误可能与我配置实体管理器工厂的方式有关。 I include the full stack trace and the configuration class below. 我在下面包括完整的堆栈跟踪和配置类。

The full stack trace is: 完整的堆栈跟踪为:

12:24:15.278 [main] WARN  net.sf.ehcache.config.ConfigurationFactory - No configuration found. Configuring ehcache from ehcache-failsafe.xml  found in the classpath: jar:file:/C:/Users/crodriguez/.m2/repository/net/sf/ehcache/ehcache-core/2.4.3/ehcache-core-2.4.3.jar!/ehcache-failsafe.xml    
12:24:15.470 [main] ERROR org.hibernate.AssertionFailure - HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: Table example.BASE_CLASSES not found    
12:24:15.470 [main] WARN  org.springframework.context.annotation.AnnotationConfigApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'exampleEntityManagerFactory' defined in class path resource [com/example/demo/configuration/JPAConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: persistence-unit] Unable to build Hibernate SessionFactory    
12:24:15.500 [main] ERROR org.springframework.boot.SpringApplication - Application startup failed    
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'exampleEntityManagerFactory' defined in class path resource [com/example/demo/configuration/JPAConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: persistence-unit] Unable to build Hibernate SessionFactory    
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583)    
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)    
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)    
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)    
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)    
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)    
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)    
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1076)    
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:851)    
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)    
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761)    
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371)    
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)    
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186)    
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175)    
    at com.example.demo.JoinedInheritanceErrorDemoApplication.main(JoinedInheritanceErrorDemoApplication.java:10)    
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: persistence-unit] 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.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)    
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353)    
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373)    
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362)    
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1642)    
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)    
    ... 15 common frames omitted    
Caused by: org.hibernate.MappingException: Could not instantiate persister org.hibernate.persister.entity.JoinedSubclassEntityPersister    
    at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:112)    
    at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:77)    
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:348)    
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444)    
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879)    
    ... 21 common frames omitted    
Caused by: org.hibernate.AssertionFailure: Table example.BASE_CLASSES not found    
    at org.hibernate.persister.entity.AbstractEntityPersister.getTableId(AbstractEntityPersister.java:5118)    
    at org.hibernate.persister.entity.JoinedSubclassEntityPersister.<init>(JoinedSubclassEntityPersister.java:433)    
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)    
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)    
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)    
    at java.lang.reflect.Constructor.newInstance(Unknown Source)    
    at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:96)    
    ... 25 common frames omitted    

My Configuration class is: 我的配置类是:

@Configuration    
@ComponentScan(basePackages = { "com.example.demo" })    
@EnableJpaRepositories(basePackages = {    
        "com.example.demo" }, entityManagerFactoryRef = JPAConfiguration.ENTITY_MANAGER_NAME, transactionManagerRef = JPAConfiguration.TRANSACTION_MANAGER_NAME)    
@PropertySource("classpath:database.properties")    
public class JPAConfiguration {    

    public static final String ENTITY_MANAGER_NAME = "entityManagerFactory";    
    public static final String TRANSACTION_MANAGER_NAME = "transactionManager";    
    public static final String PERSITENCE_UNIT_NAME = "persistence-unit";    

    private @Value("${example.datasource.url}") String datasourceUrl;    
    private @Value("${example.datasource.username}") String username;    
    private @Value("${example.datasource.password}") String password;    
    private @Value("${example.datasource.driverClassName}") String driverClassName;    
    private @Value("${example.datasource.max-active}") Integer maxActive;    
    private @Value("${example.datasource.max-idle}") Integer maxIdle;    
    private @Value("${example.datasource.min-idle}") Integer minIdle;    
    private @Value("${example.datasource.max-wait}") Integer maxWait;    
    private @Value("${example.datasource.initial-size}") Integer initialSize;    
    private @Value("${example.datasource.schema}") String defaultSchema;    

    @Bean    
    @Primary    
    public DataSource exampleDataSource() {    

        PoolProperties properties = new PoolProperties();    
        properties.setUrl(datasourceUrl);    
        properties.setUsername(username);    
        properties.setPassword(password);    
        properties.setDriverClassName(driverClassName);    
        properties.setInitialSize(initialSize);    
        properties.setMaxActive(maxActive);    
        properties.setMaxIdle(maxIdle);    
        properties.setMaxWait(maxWait);    
        properties.setMinIdle(minIdle);    

        return new DataSource(properties);    

    }    

    @Bean    
    @Primary    
    public LocalContainerEntityManagerFactoryBean exampleEntityManagerFactory() {    

        LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();    
        Properties properties = new Properties();    
        properties.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.SingletonEhCacheProvider");    
        properties.setProperty("hibernate.cache.use_second_level_cache", "true");    
        properties.setProperty("hibernate.cache.use_query_cache", "true");    
        properties.setProperty("hibernate.cache.use_structured_entries", "true");    
        properties.setProperty("hibernate.cache.region.factory_class",    
                "org.hibernate.cache.ehcache.EhCacheRegionFactory");    
        properties.setProperty("jadira.usertype.autoRegisterUserTypes", "true");    
        properties.setProperty("jadira.usertype.databaseZone", "jvm");    
        properties.setProperty("javax.persistence.sharedCache.mode", "ENABLE_SELECTIVE");    
        properties.setProperty("hibernate.generate_statistics", "false");    
        properties.setProperty("hibernate.hbm2ddl.auto", "create");    
        properties.setProperty("hibernate.default_schema", defaultSchema);    

        entityManager.setPackagesToScan("com.example.demo.model");    
        entityManager.setJpaVendorAdapter(new HibernateJpaVendorAdapter());    
        entityManager.setPersistenceUnitName(PERSITENCE_UNIT_NAME);    
        entityManager.setJpaProperties(properties);    
        entityManager.setDataSource(exampleDataSource());    

        return entityManager;    
    }    

    @Bean    
    @Primary    
    public PlatformTransactionManager defaultTransactionManager() {    

        JpaTransactionManager transactionManager = new JpaTransactionManager();    
        transactionManager.setEntityManagerFactory(exampleEntityManagerFactory().getObject());    
        return transactionManager;    
    }    

}

I have uploaded the code to reproduce the error to my GitHub: https://github.com/CarlosR-B/JoinedInheritanceError 我已将代码重现错误以上传到我的GitHub: https : //github.com/CarlosR-B/JoinedInheritanceError

EDIT 编辑

I tried to find out what was causing the different behaviour between the testing framework and Spring Boot. 我试图找出是什么导致了测试框架和Spring Boot之间的不同行为。 I found that the error happens when creating an EntityPerister on the Hibernate class MetamodelImpl . 我发现在Hibernate类MetamodelImpl上创建EntityPerister时发生错误。

The only thing that I could find was that, when building the EntityPersister, the testing framework is using a null accessStrategy and Spring Boot is using NonstopAwareEntityRegionAccessStrategy . 我唯一能发现的是,在构建EntityPersister时,测试框架使用的是null accessStrategy,而Spring Boot使用的是NonstopAwareEntityRegionAccessStrategy

If you are using MySQL database, you might be facing the following problem: https://hibernate.atlassian.net/browse/HHH-10490 如果使用的是MySQL数据库,则可能会遇到以下问题: https : //hibernate.atlassian.net/browse/HHH-10490

Change the following line: 更改以下行:

properties.setProperty("hibernate.default_schema", defaultSchema);

to: 至:

properties.setProperty("hibernate.default_catalog", defaultSchema);

Note that you might want to change the attribute name from "defaultSchema" to "defaultCatalog" as well. 请注意,您可能还希望将属性名称从“ defaultSchema”更改为“ defaultCatalog”。

Edit: Note about database. 编辑:关于数据库的说明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM