0

So I've inherited a code base at my new job and the only other java dev here is also pretty new. I'm trying to run a spring-boot project that takes files and inserts the contents into a database (as far as I understand it), but I'm getting the following error on startup:

`org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: Missing table: header
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
    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:1054)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:829)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:760)
    at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:360)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:306)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174)
    at com.mycompany.myproject.config.Application.main(Application.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:478)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.hibernate.HibernateException: Missing table: header
    at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1335)
    at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:175)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:525)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1859)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:857)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850)
    at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:425)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:849)
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:319)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
    ... 22 more`

The main Application.java:

package com.mycompany.myproject.config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

import javax.sql.DataSource;

@EnableAutoConfiguration
@Configuration
@ComponentScan(basePackages = "com.mycompany")
@EnableJpaRepositories("com.mycompany.myproject.database.repositories")
@EntityScan(basePackages = "com.mycompany.myproject.database.entities")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean(name = "primaryDataSource")
    @ConfigurationProperties(prefix = "datasource.primary")
    @Primary
    public DataSource configDataSource() {
        return DataSourceBuilder.create().build();
    }

} 

The bean for the 'header' that it seems to think is missing:

package com.mycompany.myproject.database.entities;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.Temporal;

@Data
@Entity
@Table(name = "header")
public class Header extends EntityBase {

    @Column(nullable = false)
    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
    private Date startDate;

    @Temporal(javax.persistence.TemporalType.TIMESTAMP)
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss")
    private Date endDate;

    @Column(nullable = false)
    private String processName;

    @Column(nullable = false)
    private String fileName;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "header")
    private List<Item> itemList;

}

I've trawled through all the vaguely related questions here I could find but none of the answers have worked for me.

Happy to post more code or specific configuration details if required.

wayne649
  • 21
  • 1
  • 4
  • Does the table really exist in your DB? – elyor Nov 29 '18 at 16:43
  • worth looking into this post https://stackoverflow.com/questions/18716204/hibernate-help-in-resolving-exception-org-hibernate-hibernateexception-missin – Ashish Patil Nov 29 '18 at 16:44
  • @elyor I actually haven't been able to figure out which database this is pointing to (any clues as to where this is configured would be greatly appreciated) but there are currently production and UAT versions of the service running on different servers so I assume the tables are in order. To make things slightly more confusing I've tried copying the war and application.properties from the UAT server onto a new instance and I'm getting the same error on startup (I can restart without issue on the current UAT server). – wayne649 Dec 03 '18 at 10:17
  • @wayne649 You can try to find out which db/host instance your hibernate is connecting (you can write log or debug your app). Here are some tips: https://stackoverflow.com/questions/4351443/how-to-know-underlying-database-name-from-hibernate-provider – elyor Dec 03 '18 at 10:52
  • So I don't seem to be able to find the database info by debugging locally, I think this might be because it hasn't been set up. I'm trying to figure out what is different between there and the working servers, it seems to be using HSQLDB to create what I assume is a temporary database but that's mostly a guess on my part and I'm struggling to find any configuration behind it. – wayne649 Dec 03 '18 at 15:06
  • From the application.properties: `datasource.primary.driverClassName=org.hsqldb.jdbc.JDBCDriver datasource.primary.url=jdbc:hsqldb:file:db/filelog` If this means more to anyone else than it does to me I'd appreciate the help. – wayne649 Dec 03 '18 at 15:08

2 Answers2

0

The log says:

Caused by: org.hibernate.HibernateException: Missing table: header

Check if the app is correctly configurated and if the table exists in DDBB.

José Ricardo Pla
  • 1,043
  • 10
  • 16
0

Turned out there was something wrong in the generated hsqldb.script file that meant the database user was failing authentication, I'm still not fully sure what was wrong or how this file was generated but I copied the bulk of it over from one of the working servers and that allowed the service to start up.

wayne649
  • 21
  • 1
  • 4