Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Configure SpringBoot+Hibernate+PostgreSQL

I'm totally noob in PostgreSQL and configuring Spring web applications, plus all info I could found about this is on Maven or for Eclipse, so very hard for me understand cause I'm using IntelliJ + Gradle. Installed Postgres v 9.5.4.2 on my iMac and started simple web app:

UPDATE: All fixes made, M. Deinum, gradle-2.13 is ok for SpringBoot?

Project structure:

enter image description here

build.gradle:

buildscript {
    ext {
        springBootVersion = '1.3.7.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'spring-boot'

jar {
    baseName = 'TryPostgreSQL'
    version = '0.0.1-SNAPSHOT'
}

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web'
    compile 'org.springframework.boot:spring-boot-starter-thymeleaf'
    compile 'org.springframework.boot:spring-boot-starter-data-jpa'
    compile 'org.springframework.boot:spring-boot-starter-security'
    compile 'org.springframework.boot:spring-boot-starter-aop'
    compile 'org.thymeleaf.extras:thymeleaf-extras-springsecurity4'
    compile 'com.google.code.gson:gson'
    compile 'org.postgresql:postgresql'

    testCompile 'org.springframework.boot:spring-boot-starter-test'
    testCompile("org.dbunit:dbunit:2.5.1")
    testCompile("com.github.springtestdbunit:spring-test-dbunit:1.2.1")
    testCompile("net.sourceforge.htmlunit:htmlunit:2.20")
    testCompile("org.easytesting:fest-assert:1.4")
    testCompile ("org.springframework.security:spring-security-test")
}

task wrapper(type: Wrapper) {
    gradleVersion = '3.0'
}

task stage {
    dependsOn build
}

Application.java

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

application.properties (no idea why, but dialect attribute is bold red):

# Details for our datasource
spring.datasource.url = jdbc:postgresql://localhost:5432/database
spring.datasource.username = postgres
spring.datasource.password = postgres

# Hibernate properties
spring.jpa.database = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.show-sql = false
spring.jpa.hibernate.ddl-auto = create-drop
spring.jpa.hibernate.naming.implicit-strategy = org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
spring.jpa.properties.hibernate.format_sql=true

And error message of course:

2016-09-16 09:17:19.978  WARN 773 --- [           main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
2016-09-16 09:17:19.985  INFO 773 --- [           main] o.apache.catalina.core.StandardService   : Stopping service Tomcat
2016-09-16 09:17:19.996 ERROR 773 --- [           main] o.s.boot.SpringApplication               : Application startup failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.dataSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$NonEmbeddedConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]

Other code - just usual model (my entities), dao (Crud repositories), service and controllers. Anyway I can't even start it, getting this error message right after boot:

I will be greatly appreciated for any help to start this program and connect it to PostgeSQL database.

UPDATE 2: Moved. Refreshed. Error:

Properties configuration failed validation
2016-09-16 09:41:53.696 ERROR 883 --- [           main] o.s.b.b.PropertiesConfigurationFactory   : Field error in object 'spring.jpa' on field 'database': rejected value [org.hibernate.dialect.PostgreSQLDialect]; codes [typeMismatch.spring.jpa.database,typeMismatch.database,typeMismatch.org.springframework.orm.jpa.vendor.Database,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [spring.jpa.database,database]; arguments []; default message [database]]; default message [Failed to convert property value of type [java.lang.String] to required type [org.springframework.orm.jpa.vendor.Database] for property 'database'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [org.springframework.orm.jpa.vendor.Database] for value 'org.hibernate.dialect.PostgreSQLDialect'; nested exception is java.lang.IllegalArgumentException: No enum constant org.springframework.orm.jpa.vendor.Database.org.hibernate.dialect.PostgreSQLDialect]

UPDATE 3: Changed name of property in application.property from database to dialect. Application started!

like image 483
zzheads Avatar asked Sep 15 '16 22:09

zzheads


1 Answers

You are using Spring Boot (at least that is what you state) but your code shows that you are trying really hard not to use Spring Boot.

First your Application class, ideally that should be in a top-level pacakage like com.zzheads.trypostgresql. With that you can remove the @ComponentScan and simply replace all the annotations with a simple @SpringBootApplication annotation. (note the removal of the static section as well!).

@SpringBootApplication
public class Application {

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

Next your dependencies. Spring Boot provides starter projects those are there for the fact that it saves you hunting for dependencies. Fix those dependencies to use the Spring Boot Starters. Try to use the latests 1.3.7.RELEASE of Spring Boot (as you seem to use the 1.3 line).

springBootVersion = '1.3.7.RELEASE'

Note: The Spring Boot plugin (and dependencies plugin) currently don't work with Gradle 3 (see this ).

Dependencies

dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web'
    compile 'org.springframework.boot:spring-boot-starter-thymeleaf'
    compile 'org.springframework.boot:spring-boot-starter-data-jpa'
    compile 'org.springframework.boot:spring-boot-starter-security'
    compile 'org.springframework.boot:spring-boot-starter-aop'
    compile 'org.thymeleaf.extras:thymeleaf-extras-springsecurity4'
    compile 'com.google.code.gson:gson'
    compile 'org.postgresql:postgresql'

    testCompile 'org.springframework.boot:spring-boot-starter-test'
    testCompile("org.dbunit:dbunit:2.5.1")
    testCompile("com.github.springtestdbunit:spring-test-dbunit:1.2.1")
    testCompile("net.sourceforge.htmlunit:htmlunit:2.20")
    testCompile("org.easytesting:fest-assert:1.4")
    testCompile ("org.springframework.security:spring-security-test")
}

Spring Boot also provides dependency management so you can remove versions of already managed dependencies.

Next Spring Boot already configures a DataSource and JPA for you. You don't need to do it yourself. So just remove your DataConfig.

Finally your application.properties that will be loaded by Spring Boot for you if you put it in the correct location. Move it to one of those locations.

Now to be able to automatically configure the datasource and JPA use the proper property names.

# Details for our datasource
spring.datasource.url = jdbc:postgresql://localhost:5432/database
spring.datasource.username = postgres
spring.datasource.password = postgres

# Hibernate properties
spring.jpa.database-platform = org.hibernate.dialect.PostgreSQL94Dialect
spring.jpa.show-sql = false
spring.jpa.hibernate.ddl-auto = create-drop
spring.jpa.hibernate.naming.implicit-strategy = org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
spring.jpa.properties.hibernate.format_sql=true

Note: Make sure that the application.properties is in src/main/resources and not src/main/java. If they are in the latter Maven/Gradle will ignore them.

If the entities are in a subpackage of com.zzheads.trypostgresql they will be automatically detected already and you don't need to add anything. If they aren't add an @EntityScan annotation to your Application class to fix that. The same applies to your JPA repositories, if they are in a subpackage you don't need to do anything.

like image 170
M. Deinum Avatar answered Oct 05 '22 23:10

M. Deinum