I'm trying to build a H2 database using Spring, but I'm running into errors. I've so far followed the steps from this channel, but I'm running into this error:
2022-12-30T22:04:01.054+11:00 WARN 18528 --- [ main] o.h.t.s.i.ExceptionHandlerLoggedImpl : GenerationTarget encountered exception accepting command : Error executing DDL "INSERT INTO courses VALUES (id, code, coursename) VALUES (1, 'CS150', 'Intro to Computer Science')" via JDBC Statement
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "INSERT INTO courses VALUES (id, code, coursename) VALUES (1, 'CS150', 'Intro to Computer Science')" via JDBC Statement
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) ~[hibernate-core-6.1.6.Final.jar:6.1.6.Final]
(the error continues...)
Model
package com.example.SpringPractice.model;
// imports
#Entity
#Table(name = "courses")
public class Course {
#Id
#GeneratedValue
private Long id;
private String code;
private String coursename;
}
Repository
package com.example.SpringPractice.repository;
import com.example.SpringPractice.model.Course;
import org.springframework.data.repository.CrudRepository;
public interface CourseRepository extends CrudRepository<Course, Long> {
}
Dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
Main
package com.example.SpringPractice;
// imports
#SpringBootApplication
public class SpringPracticeApplication {
#Autowired
private CourseRepository courseRepository;
public static void main(String[] args) {
SpringApplication.run(SpringPracticeApplication.class, args);
}
#PostConstruct
private void postInit() {
System.out.println("All courses: " + courseRepository.findAll());
}
}
application.properties
spring.jpa.hibernate.ddl-auto=create
spring.datasource.url = jdbc:h2:mem:course-db
SQL statement
INSERT INTO courses VALUES (id, code, coursename) VALUES (1, 'CS150', 'Intro to Computer Science')
I've tried changing what's in application.properties, dependencies (javax to jakarta).
Mistake in the SQL statement. Facepalm..
I missed the "caused by" in the error logs which helped answer the problem.
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "INSERT INTO courses VALUES (id, code, coursename) [*]VALUES (1, CS150, Intro to Computer Science)"; SQL statement:
Fixed SQL statement with:
INSERT INTO courses(id, code, coursename) VALUES (1, 'CS150', 'Intro to Computer Science')
Related
This question already has answers here:
The server time zone value 'AEST' is unrecognized or represents more than one time zone
(15 answers)
MySQL JDBC Driver 5.1.33 - Time Zone Issue
(35 answers)
Closed 2 years ago.
I am building a simple CRUD operation using Spring Boot, MySQL and Hibernate need help in this operation. Searched a lot at Google and StackOverflow didn't found an appropriate solution.
Issues on: The server time zone value 'unknown' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specific time zone value if you want to utilize time zone support.
com.mysql.cj.core.exceptions.InvalidConnectionAttributeException: The server time zone value 'unknown' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_91]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_91]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_91]
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_91]
The server time zone value 'unknown' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
Unable to open JDBC Connection for DDL execution
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:69) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.jdbcStatement(GenerationTargetToDatabase.java:77) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:53) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlString(SchemaDropperImpl.java:375) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlStrings(SchemaDropperImpl.java:359) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.tool.schema.internal.SchemaDropperImpl.dropFromMetadata(SchemaDropperImpl.java:241) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.tool.schema.internal.SchemaDropperImpl.performDrop(SchemaDropperImpl.java:154) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:126) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:112) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:145) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:73) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:316) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:469) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
[PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.GenericJDBCException: Unable to open JDBC Connection for DDL execution
Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.GenericJDBCException: Unable to open JDBC Connection for DDL execution
Error creating bean with name 'digitalEmployeeRepo' defined in com.eg.demo.repository.DigitalEmployeeRepo defined in #EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Cannot resolve reference to bean 'jpaMappingContext' while setting bean property 'mappingContext'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.GenericJDBCException: Unable to open JDBC Connection for DDL execution
.................................................................
My codes.
.............
Controller
...........................
package com.eg.demo.controller;
import com.eg.demo.model.DigitalEmployee;
import com.eg.demo.service.DigitalEmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.List;
public class DigitalController {
#Autowired
DigitalEmployeeService digitalEmployeeService;
#RequestMapping(value = "/DigitalEmployee/", method = RequestMethod.GET)
public ResponseEntity<List<DigitalEmployee>> listAllUsers() {
List<DigitalEmployee> digitalEmployees = digitalEmployeeService.allEmployee();
if (digitalEmployees.isEmpty()) {
return new ResponseEntity(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<List<DigitalEmployee>>(digitalEmployees, HttpStatus.OK);
}
// -------------------Retrieve Single User------------------------------------------
#RequestMapping(value = "/digitalEmployee/{id}", method = RequestMethod.GET)
public ResponseEntity<?> getEmployee(#PathVariable("id") long id) {
DigitalEmployee digitalEmployee = digitalEmployeeService.findById(id);
return new ResponseEntity<DigitalEmployee>(digitalEmployee, HttpStatus.OK);
}
// -------------------Create a User-------------------------------------------
#RequestMapping(value = "/digitalEmployee/", method = RequestMethod.POST)
public ResponseEntity<?> createEmployee(#RequestBody DigitalEmployee digitalEmployee) {
digitalEmployeeService.save(digitalEmployee);
return new ResponseEntity<DigitalEmployee>(HttpStatus.CREATED);
}
// ------------------- Update a User ------------------------------------------------
#RequestMapping(value = "/digitalEmployee/{id}", method = RequestMethod.PUT)
public ResponseEntity<?> updateEmployee(#PathVariable("id") long id, #RequestBody DigitalEmployee digitalEmployee) {
DigitalEmployee currentEmployee = digitalEmployeeService.findById(id);
currentEmployee.setName(digitalEmployee.getName());
digitalEmployeeService.update(currentEmployee);
return new ResponseEntity<DigitalEmployee>(currentEmployee, HttpStatus.OK);
}
// ------------------- Delete a User-----------------------------------------
#RequestMapping(value = "/digitalEmployee/{id}", method = RequestMethod.DELETE)
public ResponseEntity<?> deleteEmployee(#PathVariable("id") long id) {
DigitalEmployee digitalEmployee = digitalEmployeeService.findById(id);
digitalEmployeeService.deleteById(id);
return new ResponseEntity<DigitalEmployee>(HttpStatus.NO_CONTENT);
}
// ------------------- Delete All Users-----------------------------
#RequestMapping(value = "/DigitalEmployee/", method = RequestMethod.DELETE)
public ResponseEntity<DigitalEmployee> deleteAll() {
digitalEmployeeService.deleteAll();
return new ResponseEntity<DigitalEmployee>(HttpStatus.NO_CONTENT);
}
}
model
.................
package com.eg.demo.model;
import javax.persistence.*;
#Entity
#Table(name = "DigitalEmployee")
public class DigitalEmployee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column
private String name;
public DigitalEmployee() {
}
public DigitalEmployee(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
...........
repo
.............
package com.eg.demo.repository;
import com.eg.demo.model.DigitalEmployee;
import org.springframework.data.repository.CrudRepository;
public interface DigitalEmployeeRepo extends CrudRepository<DigitalEmployee, Long> {
}
...............................
service
............
package com.eg.demo.service;
import com.eg.demo.model.DigitalEmployee;
import java.util.List;
import java.util.Optional;
public interface DigitalEmployeeService {
void save(DigitalEmployee digitalEmployee);
void update(DigitalEmployee digitalEmployee);
void deleteAll();
void deleteById(Long id);
DigitalEmployee findById(Long id);
List<DigitalEmployee> allEmployee();
}
.............
service Impl
..................
package com.eg.demo.service;
import com.eg.demo.model.DigitalEmployee;
import com.eg.demo.repository.DigitalEmployeeRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
#Service
public class DigitalEmployeeServiceImpl implements DigitalEmployeeService {
#Autowired
DigitalEmployeeRepo digitalEmployeeRepo;
public void save(DigitalEmployee digitalEmployee) {
digitalEmployeeRepo.save(digitalEmployee);
}
public void update(DigitalEmployee digitalEmployee) {
save(digitalEmployee);
}
public void deleteAll() {
digitalEmployeeRepo.deleteAll();
}
public void deleteById(Long id) {
digitalEmployeeRepo.deleteById(id);
}
public DigitalEmployee findById(Long id) {
return digitalEmployeeRepo.findById(id).get();
}
public List<DigitalEmployee> allEmployee() {
return (List<DigitalEmployee>) digitalEmployeeRepo.findAll();
}
}
............
main method
...........
package com.eg.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
//#Configuration
#SpringBootApplication(scanBasePackages = "com.*")
#EnableSwagger2
//#EnableAutoConfiguration
//#ComponentScan("com.eg.demo")
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}
................
applicaion properties
............................
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.show-sql=true
spring.datasource.url=jdbc:mysql://localhost:3306/digital
spring.datasource.username=root
spring.datasource.password=
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.format_sql=true
.......................
pom
...............................
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.eg</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<!--<dependency>-->
<!--<groupId>io.springfox</groupId>-->
<!--<artifactId>springfox-swagger2</artifactId>-->
<!--<version>2.9.2</version>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>io.springfox</groupId>-->
<!--<artifactId>springfox-swagger2</artifactId>-->
<!--<version>2.9.2</version>-->
<!--</dependency>-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-spring-web</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-oas</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-hateoas</artifactId>
</dependency>
<!--<dependency>-->
<!--<groupId>io.springfox</groupId>-->
<!--<artifactId>springfox-swagger-ui</artifactId>-->
<!--<version>2.9.2</version>-->
<!--</dependency>-->
<!---->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
config the timezone with the datasource url property, just like this
url:jdbc:mysql://127.0.0.1:3306/test?&serverTimezone=Asia/Shanghai
spring.datasource.url=jdbc:mysql://localhost:3306/digital?serverTimezone=UTC
I have a simple Dog entity:
Dog.java:
#Entity
#Table(name = "dogs")
public class Dog {
public Dog() {}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
DogController.java:
#RestController
public class DogController {
#Autowired
private DogRepository dogRepository;
#RequestMapping("/api/dogs/insert/default")
#Transactional
public String insertDefault() {
Dog dog = new Dog();
dog.setName("Alpha dog");
dogRepository.save(dog);
return "dog inserted OK";
}
}
DogRepository:
#Repository
public interface DogRepository extends JpaRepository<Dog, Long> {
}
However when I go to /api/dogs/insert/default it simply displays dog inserted OK without changing a database or even attempting to change it (no queries are printed to the console).
What could be the problem here? In debugger I can see that dogRepository is not null.
My WebMvcConfigurer class looks like this:
#EnableWebMvc
#Configuration
#EnableJpaRepositories("testproject")
#EnableTransactionManagement
#ComponentScan("testproject")
public class WebConfig implements WebMvcConfigurer {...}
I tried adding the #EnableTransactionManagement to it, but it didn't work
EDIT:
I don't have an application.properties file. All properties are configured using Java classes.
DbConfig.java:
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(basePackages = "testproject", entityManagerFactoryRef = "entityManagerFactory")
public class DbConfig {
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(getDatasource());
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
entityManagerFactoryBean.setJpaProperties(getHibernateProperties());
entityManagerFactoryBean.setPackagesToScan("testproject");
return entityManagerFactoryBean;
}
#Bean
public DataSource getDatasource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl("jdbc:postgresql://127.0.0.1:5432/testproject");
dataSource.setUsername("postgres");
dataSource.setPassword("bigfalcon");
return dataSource;
}
#Bean
public SessionFactory getSessionFactory() throws IOException {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setPackagesToScan("testproject");
//getHibernateProperties method is a private method
sessionFactoryBean.setHibernateProperties(getHibernateProperties());
sessionFactoryBean.setDataSource(getDatasource());
sessionFactoryBean.afterPropertiesSet();
return sessionFactoryBean.getObject();
}
#Bean(name = "transactionManager")
public HibernateTransactionManager getTransactionManager() throws IOException {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(getSessionFactory());
return transactionManager;
}
#Bean
private static Properties getHibernateProperties() {
Properties hibernateProperties = new Properties(); //PostgreSQLDialect
//hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
hibernateProperties.put("hibernate.show_sql", true);
// hibernateProperties.put("spring.jpa.hibernate.ddl-auto", "create");
hibernateProperties.put( "hibernate.hbm2ddl.auto", "create-drop");
/*hibernateProperties.setProperty(
"hibernate.dialect", "org.hibernate.dialect.H2Dialect");
*/
System.out.println();
// other properties
return hibernateProperties;
}
}
EDIT:
Using the same dogRepository to select existing dogs from the database (which I manually inserted) works fine:
#RequestMapping("/api/dogs/view/all")
public Iterable<Dog> viewDogs() {
Iterable<Dog> dogs = dogRepository.findAll(); //non-null size, returns a JSON with dogs
return dogs;
}
EDIT: Maven dependencies:
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.3.1.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-core -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>5.3.1.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-config -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.3.1.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-web -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.3.1.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>3.0.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.opennlp</groupId>
<artifactId>opennlp-tools</artifactId>
<version>1.9.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.dv8tion/JDA -->
<dependency>
<groupId>net.dv8tion</groupId>
<artifactId>JDA</artifactId>
<version>4.0.0_46</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.4.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.197</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1203-jdbc4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security.oauth/spring-security-oauth2 -->
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.4.1.RELEASE</version>
</dependency>
<!--is needed for jwt-->
<!-- https://mvnrepository.com/artifact/javax.xml/jaxb-api -->
<dependency>
<groupId>javax.xml</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-impl -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>3.0.0-M4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-core -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>3.0.0-M4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-jwt -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<version>1.1.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.jakewharton.fliptables/fliptables -->
<dependency>
<groupId>com.jakewharton.fliptables</groupId>
<artifactId>fliptables</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.4.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20190722</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
</dependencies>
EDIT:
I also tried to get it to update the entity:
#RequestMapping("/api/dogs/update/{id}")
public Iterable<Dog> updateDog(#PathVariable("id") long id) {
Optional<Dog> dog = dogRepository.findById(id);
Dog dogValue = dog.get();
dogValue.setName("New name");
dogRepository.save(dogValue);
return dogRepository.findAll();
}
which however doesn't work: the JSON returned to the browser contains updated name (New name), but doesn't update the database itself.
EDIT:
I managed to get it to work with manual Hibernate commands, see the added methods insertDog(Dog dog) and updateDog(Dog dog): I take the Session object from autowired DbConfig object and use session.save(dog), session.flush() to update the database. With the following controller code both /api/dogs/insert/default and /api/dogs/update/3/Buddy work fine.
So the problem seems to be related to JpaRepository specifically, seeing as if I forego using it and write the Hibernate code myself, it works fine:
DogController.java:
#CrossOrigin
#RestController
#Transactional( readOnly = false)
public class DogController {
#Autowired
private DogRepository dogRepository;
#Autowired
private DbConfig dbConfig;
#RequestMapping("/api/dogs/insert/default")
#Transactional(readOnly=false)
public String insertDefault() throws Exception {
Dog dog = new Dog();
dog.setName("Alpha dog");
//dogRepository.save(dog);
insertDog(dog);
return "dog inserted OK";
}
#RequestMapping("/api/dogs/view/all")
public Iterable<Dog> viewDogs() {
Iterable<Dog> dogs = dogRepository.findAll();
return dogs;
}
#RequestMapping("/api/dogs/update/{id}/{name}")
public Iterable<Dog> updateDog(#PathVariable("id") long id,
#PathVariable("name") String name) throws Exception {
Optional<Dog> dog = dogRepository.findById(id);
Dog dogValue = dog.get();
dogValue.setName(name);
//dogRepository.save(dogValue);
Session session = dbConfig.getSessionFactory().openSession();
updateDog(dogValue);
return dogRepository.findAll();
}
public void updateDog(Dog dog) throws Exception {
Session session = dbConfig.getSessionFactory().openSession();
session.beginTransaction();
session.merge(dog);
session.flush();
session.getTransaction().commit();
session.clear();
session.close();
}
public boolean insertDog(Dog dog) throws Exception {
boolean result = false;
Session session = dbConfig.getSessionFactory().openSession();
session.beginTransaction();
try {
session.save(dog);
session.flush();
session.getTransaction().commit();
result = true;
}
catch (Exception e) {
result = false;
}
finally {
session.clear();
session.close();
}
return result;
}
}
EDIT:
I wonder if something to do with generating ids of the Dog entity could be the problem. I use PostgreSQL and in the logs I see
WARN [RMI TCP Connection(2)-127.0.0.1] org.hibernate.engine.jdbc.spi.SqlExceptionHelper$StandardWarningHandler.logWarning sequence "hibernate_sequence" does not exist, skipping
And then when I access /api/dogs/insert/default in console
Hibernate: select nextval ('hibernate_sequence')
gets printed.
I tried changing GenerationStrategy but it didn't help. I also tried adding
hibernateProperties.put("hibernate.connection.driver_class", "org.postgresql.Driver");
to getHibernateProperties() method in DbConfig.java but it didn't seem to help either.
EDIT:
I also tried changing HibernateTransactionManager to JpaTransactionManager in transactionManager() method in DbConfig.java:
#Bean(name = "transactionManager")
public JpaTransactionManager transactionManager() throws IOException {
JpaTransactionManager transactionManager = new JpaTransactionManager();
//transactionManager.setSessionFactory(getSessionFactory());
return transactionManager;
}
but that resulted the
NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManagerFactory' available: more than one 'primary' bean found among candidates: [entityManagerFactory, getSessionFactory]
error on server startup
I also figured that maybe JpaRepository can't generate the id, so I tried making it manual:
#Id
#Column(name = "dog_id", unique = true, nullable = false)
private Long id;
and in DogController.java:
#RequestMapping("/api/dogs/insert/default")
#Transactional(readOnly=false, propagation = Propagation.REQUIRED)
public String insertDefault() throws Exception {
Dog dog = new Dog();
Random random = new Random();
dog.setId((long) random.nextInt(1000_000_000));
dog.setName("Alpha dog");
dogRepository.save(dog);
dogRepository.flush();
//insertDog(dog);
return "dog inserted OK";
}
however it resulted in error:
org.springframework.web.util.NestedServletException:
Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException:
no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
EDIT:
Also I figured out why there was no no transaction is in progress error earlier (that error helped understand what was wrong): the error only appeared after I added
dogRepository.flush();
to DogController.java.
If I remove dogRepository.flush() the dogRepository.save(dog) method still wouldn't work, but no visible error would appear (other than Hibernate: select nextval ('hibernate_sequence') in console).
I managed to make JpaRepository insert on /api/dogs/insert/default work!
What it took: adding
hibernateProperties.put("hibernate.allow_update_outside_transaction", true);
to getHibernateProperties() method of DbConfig.java class.
However I'm not sure that's a correct way to handle it? And if there are better methods of dealing with that error? And why that error only appeared when I use JpaRepository for inserting/updating entities, while if I use raw Hibernate commands (session.save()) the error didn't appear and updates worked fine?
Transactional is read-only by default. Write queries fails silently.
Set your annotation as #Transactional(readOnly=false)
Your configuration is almost OK, i changed a couple of things and it works on my Spring Boot v2.3.1.RELEASE.
Do you need this class public class WebConfig implements WebMvcConfigurer {...}? If yes consider annotating either public LocalContainerEntityManagerFactoryBean entityManagerFactory() or this public SessionFactory getSessionFactory() throws IOException { with #Primary. Else you will get this:
Parameter 0 of method openEntityManagerInViewInterceptorConfigurer in
org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration$JpaWebConfiguration
required a single bean, but 2 were found:
entityManagerFactory: defined by method 'entityManagerFactory' in class path resource [.../DbConfig.class]
getSessionFactory: defined by method 'getSessionFactory' in class path resource [.../DbConfig.class]
You have repeated annotations on public class WebConfig and public class DbConfig. #Configuration is enough on WebConfig.
Otherwise, it looks fine, just make sure that everywhere you define testproject as values is correct and that your postgresql is accessible:
Spring Boot v2.3.1.RELEASE:
Completed initialization in 5 ms
Hibernate: insert into dogs (name) values (?)
PostgreSQL:
postgres=# SELECT version();
version
------------------------------------------------------------
PostgreSQL 12.3, compiled by Visual C++ build 1914, 64-bit
(1 row)
postgres=#
postgres=# select * from dogs;
id | name
----+-----------
1 | Alpha dog
(1 row)
postgres=#
P.S: I tested with an empty WebConfig class, like so:
#Configuration
public class WebConfig implements WebMvcConfigurer {
}
The Query Update is not updating the MySQL DB. The method updateStatusTest is being executed and pass the test, but when I look in the database the data is the same. Below is the code I used:
mysql> SELECT * FROM spring_course_db.request;
+----+---------------------+-------------------------------------------+-------+----------------+----------+
| id | creation_date | description | state | subject | owner_id |
+----+---------------------+-------------------------------------------+-------+----------------+----------+
| 1 | 2019-09-24 20:03:28 | Pretendo obter um laptop HP, de RAM 16 GB | OPEN | Novo Laptop HP | 1 |
+----+---------------------+-------------------------------------------+-------+----------------+----------+
1 row in set (0,01 sec)
The state show be IN_PROCESS.
RequestStageRepository
package com.spring.course.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.spring.course.domain.Request;
import com.spring.course.domain.RequestStage;
import com.spring.course.enums.RequestState;
#Repository
public interface RequestStageRepository extends JpaRepository<RequestStage, Long>{
public List<RequestStage> findAllByRequestId(Long id);
#Query("UPDATE request SET state = :state WHERE id = :id")
public Request updateStatus(Long id, RequestState state);
}
RequestRepositoryTests
package com.spring.course.repository;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.spring.course.domain.Request;
import com.spring.course.domain.User;
import com.spring.course.enums.RequestState;
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
#RunWith(SpringRunner.class)
#SpringBootTest
public class RequestRepositoryTests {
#Autowired
private RequestRepository requestRepository;
#Test
public void AsaveTest() {
User owner = new User();
owner.setId(1L);
Request request = new Request(null, "Novo Laptop HP", "Pretendo obter um laptop HP", new Date(), RequestState.OPEN, owner, null);
Request createdRequest = requestRepository.save(request);
assertThat(createdRequest.getId()).isEqualTo(1L);
}
#Test
public void updateTest() {
User owner = new User();
owner.setId(1L);
Request request = new Request(1L, "Novo Laptop HP", "Pretendo obter um laptop HP, de RAM 16 GB", null, RequestState.OPEN, owner, null);
Request updatedRequest = requestRepository.save(request);
assertThat(updatedRequest.getDescription()).isEqualTo("Pretendo obter um laptop HP, de RAM 16 GB");
}
#Test
public void getByIdTest() {
Optional<Request> result = requestRepository.findById(1L);
Request request = result.get();
assertThat(request.getSubject()).isEqualTo("Novo Laptop HP");
}
#Test
public void listTest() {
List<Request> requests = requestRepository.findAll();
assertThat(requests.size()).isEqualTo(1);
}
#Test
public void listByOwnerIdTest() {
List<Request> requests = requestRepository.findAllByOwnerId(1L);
assertThat(requests.size()).isEqualTo(1);
}
#Test
public void updateStatusTest() {
int affectedRows = requestRepository.updateStatus(1L, RequestState.IN_PROCESS);
assertThat(affectedRows).isEqualTo(1);
}
}
POM:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.spring.course</groupId>
<artifactId>spring-course2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>spring-course2</name>
<description>Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Either the native update query or JPQL update query just return int which is no of records updated and also they need #Modifying annotation Update Queries
JPQL
#Modifying
#Query("update User u set u.status = :status where u.name = :name")
int updateUserSetStatusForName(#Param("status") Integer status,
#Param("name") String name);
The return value defines how many rows the execution of the query updated.
Native
You can modify the state of the database also with a native query — we just need to add the #Modifying annotation
#Modifying
#Query(value = "update Users u set u.status = ? where u.name = ?",
nativeQuery = true)
int updateUserSetStatusForNameNative(Integer status, String name);
5.3.8. Modifying Queries from spring data jpa documentation with below example
#Modifying
#Query("update User u set u.firstname = ?1 where u.lastname = ?2")
int setFixedFirstnameFor(String firstname, String lastname);
In case if you want to update record based on id and need to return the updated record, then you can use the save method
requestRepository.save(request)
Note : Make sure you have set values to all properties otherwise you will end up seeing null or default values
public class Post {
#Column(name="tags")
private String[] tags;
.
.
.
}
Post.Java
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1206-jdbc42</version>
<scope>runtime</scope>
</dependency>
POM.XML
#GetMapping("/posts")
public List<Post> getAllPosts() {
return postRepository.findAll();
}
Controller
#Repository
public interface PostRepository extends JpaRepository<Post, Long> {
}
Repository
spring.datasource.url= jdbc:postgresql://localhost:5432/arya2?useSSL=false
spring.datasource.username=****
spring.datasource.password=***
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL9Dialect
Calling Rest Get Request, http://localhost:8081/posts
NOT SHOWING and this error
There was an unexpected error (type=Internal Server Error, status=500).
could not deserialize; nested exception is org.hibernate.type.SerializationException: could not deserialize
and
java.sql.SQLFeatureNotSupportedException: Method org.postgresql.jdbc42.Jdbc42Connection.createClob() is not yet implemented.
I'm making a web application using Spring Boot and I have the functionality I want by using a in memory database(H2) but I can't connect it to the postgresql server I set up on my computer. I've been at this for some time and tried a bunch of stuff that didn't work so I set everything back to the way it was just to get it working again.
Here's my UploadController.java, it handles the upload from the server and puts it into my in memory database:
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import project.service.MediaFile;
import project.service.MediaFileRepository;
#Controller
public class UploadController {
#Autowired
private MediaFileRepository repository;
#RequestMapping(value = "/uploadmedia", method = RequestMethod.GET)
public String uploadForm() {
return "upload";
}
#RequestMapping(value = "/uploadmedia", method = RequestMethod.POST)
public String uploadSubmit(#RequestParam(value="files[]") MultipartFile[] files,
#RequestParam("tags") String tags, #RequestParam("type") String type)
{
String[] tagsArray = tags.split("\\s+");
MultipartFile file;
String name;
String tag;
String path;
for (int i = 0; i < files.length; i++) {
file = files[i];
name = file.getOriginalFilename();
path = "/Users/johannesthorkell/Developer/spring_prufa/images/" + name;
System.out.println(name);
if (!file.isEmpty()) {
try {
byte[] bytes = file.getBytes();
BufferedOutputStream stream =
new BufferedOutputStream(new FileOutputStream(new File(path)));
stream.write(bytes);
stream.close();
for (int j = 0; j < tagsArray.length; j++) {
tag = tagsArray[j].toLowerCase();
repository.save(new MediaFile(name, tag, path, type));
}
System.out.println("Success!");
} catch (Exception e) {
System.out.println("Failure... " + e.getMessage());
}
} else {
System.out.println("No file");
}
}
return "upload";
}
}
...and here's my MediaFile class, the #Entity object:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class MediaFile {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private String name;
private String tag;
private String resource;
private String type;
protected MediaFile() {}
public MediaFile(String name, String tag, String resource, String type) {
this.name = name;
this.tag = tag;
this.resource = resource;
this.type = type;
}
public String getTag() {
return tag;
}
#Override
public String toString() {
return String.format(
"MediaFile[id=%d, name='%s', tag='%s', resource='%s', type='%s']",
id, name, tag, resource, type);
}
}
...here's my pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>HBV501G</groupId>
<artifactId>Spring_Web_MVC</artifactId>
<version>0.1</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
...and finally, here's the application.properties:
spring.view.prefix=/WEB-INF/jsp/
spring.view.suffix=.jsp
multipart.maxFileSize=-1
With this setup everything works. I tried putting the following in my application.properties:
spring.datasource.url=jdbc:postgresql://localhost/test
spring.datasource.username=myusername
spring.datasource.password=mypassword
spring.datasource.driver-class-name=org.postgresql.jdbc.Driver
...Along with adding the following dependency to the pom.xml:
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1200-jdbc41</version>
</dependency>
...And then I tried mixing and matching these things and reading tutorials for a few hours to no avail.
Edit:
I removed one line and added another (at the advice of Stéphane Nicoll) so now my application.properties look like this:
spring.view.prefix=/WEB-INF/jsp/
spring.view.suffix=.jsp
multipart.maxFileSize=-1
debug=true
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=username
spring.datasource.password=password
...And my pom.xml looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>HBV501G</groupId>
<artifactId>Spring_Web_MVC</artifactId>
<version>0.1</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1200-jdbc41</version>
</dependency>
<!--<dependency>-->
<!--<groupId>com.h2database</groupId>-->
<!--<artifactId>h2</artifactId>-->
<!--</dependency>-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
With the changes to my application.properties my app now runs! But I get the following error when I submit to my POST form to UploadController.java:
2015-10-06 11:32:14.878 INFO 22287 --- [ main] project.Application : Started Application in 11.897 seconds (JVM running for 12.971)
2015-10-06 11:32:40.263 INFO 22287 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2015-10-06 11:32:40.264 INFO 22287 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2015-10-06 11:32:40.295 INFO 22287 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 31 ms
hopaskipting.pdf
2015-10-06 11:32:49.752 DEBUG 22287 --- [nio-8080-exec-3] org.hibernate.SQL : select nextval ('hibernate_sequence')
2015-10-06 11:32:49.760 WARN 22287 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: 42P01
2015-10-06 11:32:49.760 ERROR 22287 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: relation "hibernate_sequence" does not exist
Position: 17
Failure... could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
I changed the GenerationType to IDENTITY and get the following error:
2015-10-06 12:56:32.496 DEBUG 22746 --- [nio-8080-exec-7] org.hibernate.SQL : insert into media_file (name, resource, tag, type) values (?, ?, ?, ?)
2015-10-06 12:56:32.505 DEBUG 22746 --- [nio-8080-exec-7] org.hibernate.SQL : insert into media_file (name, resource, tag, type) values (?, ?, ?, ?)
Failure... A different object with the same identifier value was already associated with the session : [project.service.MediaFile#0]; nested exception is javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [project.service.MediaFile#0]
The key part of the error is:
2015-10-06 11:32:49.760 ERROR 22287 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : ERROR: relation "hibernate_sequence" does not exist
Hibernate's looking for a table named hibernate_sequence to support #GeneratedValue on MediaFile. You've configured it with AUTO at the moment. The actual behaviour then varies depending on the database you're using.
I think you have a couple of options:
Create a sequence in Postgres (CREATE SEQUENCE), named hibernate_sequence
Change to using a different generation type, e.g. GenerationType.IDENTITY
If I were you, I'd create my own dataSource bean, like:
#Configuration
public class MyConfig{
#Autowired
Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("myapp.dataSource.driver"));
dataSource.setUrl(env.getProperty("myapp.dataSource.url"));
dataSource.setUsername(env.getProperty("myapp.dataSource.username"));
dataSource.setPassword(env.getProperty("myapp.dataSource.password"));
return dataSource;
}
}
application.properties:
logging.level. = INFO
myapp.dataSource.driver =
myapp.dataSource.url =
myapp.dataSource.username =
myapp.dataSource.password =
IF you don't want to try this, you could try changing your driver org.postgresql.jdbc.Driver to org.postgresql.Driver.
It's hard to help without any logs.