Spring Boot Validation is not working with javax.validation - spring

I am working on a Spring Boot project and I am currently trying to implement validation. For example, I have the following class:
package abcdef.mypackage
import java.util.*
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.Id
import javax.validation.constraints.Email
import javax.validation.constraints.NotBlank
#Entity
class User (
#Id
#GeneratedValue
var id: Long,
#Column(name="username", unique = true, nullable = false)
#NotBlank
var username: String,
#Column(name="password", unique = false, nullable = false)
var password: String,
#Column(name="firstname", unique = false, nullable = false)
#NotBlank
var firstname: String,
#Column(name="lastname", unique = false, nullable = false)
#NotBlank
var lastname: String,
#Column(name = "birthdate", unique = false, nullable = true)
var birthdate: Date? = null,
#Column(name="email", unique = true, nullable = false)
#Email
var email: String,
#Column(name="phone", unique = true, nullable = false)
var phone: String,
)
You can see, that I have annotated all fields with the validations I want to have. Incoming requests are handled by the following controller class:
package abcdef.mypackage
import org.springframework.http.ResponseEntity
import org.springframework.validation.BindingResult
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
import org.springframework.web.server.ResponseStatusException
import javax.validation.Valid
#RestController
#RequestMapping("/api/v1/users/")
#Validated
class UserResource(val service: UserService) {
#PostMapping("/register")
#Validated
fun post(#Valid #RequestBody user: User, result: BindingResult) : ResponseEntity<Unit> {
if (result.hasErrors()) {
return ResponseEntity.badRequest().build()
}
try {
service.post(user)
} catch (e: Exception) {
return ResponseEntity.badRequest().build()
}
return ResponseEntity.ok().build()
}
}
When I now make a request with for example a blank username value, Spring Boot still accepts it and stores into the database. I have found some questions (and answers) on StackOverflow about missing dependencies, but I included all of those. You can take a look at my dependecies here:
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
</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-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
</dependencies>
I have no Idea what to do to get this validation working... I cannot see any issue in my dependencies. I also tried some variations with the usage of #Valid and #Validated but nothing worked for me.
I hope somebody sees my mistake. Thanks a lot!

Example: recommend data class + #field:NotBlank and not need #Validated

Related

Not able to resolve javax.validation.constraints.Email; package

Belo is my whole Entity class code.
package com.email.esp.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;
#Entity
#Table(name = "users", uniqueConstraints = { #UniqueConstraint(columnNames = { "email" }) })
public class User {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long userId;
#Column(nullable = false, length = 30)
private String name;
#Email(message = "Email is not valid", regexp = "(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")#(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])")
#NotEmpty(message = "Email cannot be empty")
private String email;
#Transient // meaning it will not be saved in DB
//#Size(min = 5, max = 15, message = "{register.password.size}")
private String plainPassword; // unencrytped
#Transient
private String repeatPassword;
#Column(nullable = true)
private String phone;
#Column(nullable = false, length = 500)
private String about;
#Column(nullable = true)
private String profilePic;
#Column(name="enabled")
private Boolean enabled = true;
}
I'm trying to use the spring Email core package in my spring boot project. I have added the dependency in my pom file but for some weird reason the import statement for import javax.validation.constraints.Email; is not getting resolved. Any idea why is this happening?? Here is the dependency , i have ...
<?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.7.9-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.email</groupId>
<artifactId>esp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>esp</name>
<description>Email Service Provider Using Spring Boot</description>
<properties>
<java.version>17</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-thymeleaf</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>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
javax.validation.constraints.Email annotation depends on Jakarta Bean Validation providers for validation.
You could try to add spring-boot-starter-validation dependency to your pom.xml. This dependency contains all the required dependencies (including jakarta and hibernate-validator which is a compliant validator for this)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

#Valid annotation not working on Dto class - Spring Boot

I want validate my CustomerDTO using #Valid annotation.but also being validated at the same time using the #Valid annotation but it doesn't work, please help me.
This is my controller:
import lk.navishka.loginWithSecuruty.dto.CustomerDto;
import lk.navishka.loginWithSecuruty.entity.Customer;
import lk.navishka.loginWithSecuruty.service.CustomerService;
import lk.navishka.loginWithSecuruty.util.StandradResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
#RestController
#CrossOrigin
public class CustomerController {
#Autowired
CustomerService customerService;
#RequestMapping(value = {"/register"})
public ResponseEntity saveCustomer(#Valid #RequestBody CustomerDto customer){
customerService.saveCustomer(customer);
StandradResponse success = new StandradResponse(200, "success", null);
return new ResponseEntity(success, HttpStatus.OK);
}
}
this is My CustomerDTO class
import lombok.*;
import javax.persistence.Column;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.ArrayList;
#AllArgsConstructor
#NoArgsConstructor
#Getter
#Setter
#ToString
public class CustomerDto {
#NotNull
#Size(min = 9, message = "Nic have at least 9 characters ")
private String nic;
private String address;
#NotNull
#Size(min = 5, message = "FirstName have at least 5 characters ")
private String firstName;
#NotNull
#Size(min = 5, message = "LastName have at least 5 characters ")
private String lastName;
private ArrayList<UserDto> user = new ArrayList<>();
}
this is my ErrorDetails class
import java.util.Date;
public class ErrorDetails {
private Date timestamp;
private String message;
private String details;
public ErrorDetails(Date timestamp, String message, String details) {
super();
this.timestamp = timestamp;
this.message = message;
this.details = details;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
}
this my ExceptionHandler class
import lk.navishka.loginWithSecuruty.util.ErrorDetails;
import lk.navishka.loginWithSecuruty.util.StandradResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.util.Date;
#ControllerAdvice
public class ExceptionHandler {
//handling custom validation error
#ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<?> customValidationErrorHandling(MethodArgumentNotValidException exception){
ErrorDetails errorDetails = new ErrorDetails(new Date(),"Validator Error", exception.getBindingResult().getFieldError().getDefaultMessage());
return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
}
}
i use meven this is Pom.xml file
<?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>lk.navishka</groupId>
<artifactId>LoginWithSecuruty</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.4.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.4.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.4.2</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.modelmapper/modelmapper -->
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.3.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>7.0.1.Final</version>
</dependency>
<!--security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
This is the JSON value that i use with postman
{
"nic" : "656v",
"address" : "polpitiya",
"firstName" : "nn",
"lastName" : "",
"user": [{
"userName":"username1",
"email":"sample#gmail.com",
"password":"1234"
}]
}
Try the 6.2.0.final version of hibernate-validator, it will work.
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.2.0.Final</version>
</dependency>

Kotlin SpringBoot and JPA - Problem with relation OneToMany-ManyToOne

I am trying to create a relation OneToMany between two entities and always get an error creating bean with name 'entityManagerFactory':
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-11-23 12:17:20.082 ERROR 17130 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags: [com.moises.kotlinstoreapi.model.Customer.purchases, com.moises.kotlinstoreapi.model.Purchase.purchasesLines]
...
I have created the same type of relation with other two entities (Customer with Purchase) but in this case it doesn't run...
Product code:
package com.moises.kotlinstoreapi.model
import com.fasterxml.jackson.annotation.JsonManagedReference
import java.time.LocalDateTime
import javax.persistence.*
import javax.validation.constraints.NotBlank
import javax.validation.constraints.NotEmpty
import javax.validation.constraints.NotNull
#Entity
#Table(name="products")
data class Product (
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0,
#NotBlank
val title: String = "",
#NotEmpty
val price: Double = 999.99,
#NotNull
val created_at: LocalDateTime = LocalDateTime.now(),
val update_at: LocalDateTime? = null,
/**
* Relations
*
*/
#OneToOne(mappedBy="product")
val purchaseLine: PurchaseLine? = null
)
Purchase code:
package com.moises.kotlinstoreapi.model
import com.fasterxml.jackson.annotation.JsonBackReference
import com.fasterxml.jackson.annotation.JsonManagedReference
import com.sun.istack.NotNull
import java.time.LocalDateTime
import javax.persistence.*
import javax.validation.constraints.NotEmpty
#Entity
#Table(name="purchases")
data class Purchase(
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private val id: Long=0,
#Column(name="notes", columnDefinition="TEXT")
val notes: String = "",
#NotNull
val created_at: LocalDateTime = LocalDateTime.now(),
val update_at: LocalDateTime? = null,
/**
* Relations
*
*/
//#ManyToOne(cascade = arrayOf(CascadeType.ALL),fetch= FetchType.EAGER)
//#JoinColumn(name="customer_id")
//#JsonBackReference
//val customer: Customer? = null,
#OneToMany(mappedBy="purchase", cascade=arrayOf(CascadeType.ALL), fetch=FetchType.EAGER)
#JsonManagedReference
var purchasesLines: List<PurchaseLine> = emptyList()
)
PurchaseLine code:
package com.moises.kotlinstoreapi.model
import com.fasterxml.jackson.annotation.JsonBackReference
import com.fasterxml.jackson.annotation.JsonManagedReference
import javax.persistence.*
import javax.validation.constraints.NotEmpty
#Entity
#Table(name="purchase_lines")
data class PurchaseLine(
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private val id: Long=0,
#NotEmpty
val quantity: Int = 1,
/**
* Relations
*
*/
#OneToOne(cascade = arrayOf(CascadeType.ALL))
#JoinColumn(name = "product_id")
#JsonManagedReference
val product: Product? = null,
#ManyToOne(cascade = arrayOf(CascadeType.ALL),fetch= FetchType.EAGER)
#JoinColumn(name="purchase_id")
#JsonBackReference
var purchase: Purchase? = null
)
I am usin IntelliJ with Maven and OpenJDK 11 in Ubuntu.
My pow.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 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.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.moises</groupId>
<artifactId>kotlin-store-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>kotlin-store-api</name>
<description>API store with Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<kotlin.version>1.3.50</kotlin.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-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</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>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<configuration>
<args>
<arg>-Xjsr305=strict</arg>
</args>
<compilerPlugins>
<plugin>spring</plugin>
<plugin>jpa</plugin>
</compilerPlugins>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-noarg</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>

Spring-Hibernate started on remote tomcat server is not creating tables. Drop and create works, alo data.sql is picked up correctly on localhost

Can not find the crucial reason why tables are not getting created under seamingly same conditions.
Spring tool suite 4.x is used for building the project/netbeans does the same.... ; the project is a maven built collection of code; both localhost and remote servers are using same mysql. the server is an Apache Tomcat 9 on Debian ...
Application.properties that works just fine on localhost:
spring.datasource.name=JAVAMAN2
spring.datasource.url=jdbc:mysql://localhost:3306/JAVAMAN2?useSSL=false&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&createDatabaseIfNotExist=true
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=password
#spring.datasource.password=
spring.datasource.continue-on-error=true
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create
spring.datasource.initialization-mode=always
This here makes no difference
spring.datasource.continue-on-error=true
My pom.xml looks like this:
<!-- BASIC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<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>
<scope>test</scope>
</dependency>
<!-- SPRING MAIL -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- THYMELEAF -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- MySQL Connector-J -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
<!-- JODA TIME -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<!-- DEVTOOLS -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- CONFIG PROCESOR -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- Google GSON -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<!-- SPRING SECURITY -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<!-- TOMCAT -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
There are no errors shown/logged in console. The application just runs, but wont create tables.
A few example entities
User
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "USERNAME", nullable = false)
private String username;
#Column(name = "PASSWORD", nullable = false)
private String password;
#Column(name = "ENABLED", nullable = false)
private Integer enabled;
#Column(name = "CLIENT_DB", nullable = false)
private String client_db;
#Column(name = "KOM_SIF", nullable = false)
private String komSif;
#Column(name = "ITC_KOM_SIF", nullable = false)
private String itcKomSif;
#Column(name = "UNIKEY", nullable = true)
private String unikey;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private Set<Authorities> authorities = new HashSet<>();
Authority
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
//import javax.persistence.GeneratedValue;
import javax.persistence.Id;
//import javax.persistence.GenerationType;
//import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name = "authorities")
public class Authorities {
#Id
//#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "AUTHORITY")
private String authority;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id", insertable = false, updatable = false)
private User user;
getters and setters intensionally omitted from this post ...
It turned out that it is a MariaDB on the remote server, not a MySQL one.
I had to replace in the pom.xmlthe mysql connector dependency with:
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
</dependency>
Also changed 3 lines to the application.properties, driver class name, url and db dialect props have been altered
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb://localhost:3308/JAVAMAN2?createDatabaseIfNotExist=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDB53Dialect
Now it creates the requiered tables the same way as it does with MySQL

Using JPA + H2 with Spring Boot + Kotlin - Error booting

I have a very simple sample Spring Boot + Kotlin project.
I added all the basic dependencies:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</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-thymeleaf</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>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
I have annotated two model classes with JPA annotations:
#Entity
class Author(
#Id #GeneratedValue(strategy = GenerationType.AUTO) val id: Long,
val firstName: String,
val lastName: String,
#ManyToMany(mappedBy = "authors") val books: Set<Book> = emptySet()
)
and
#Entity
class Book(
#Id #GeneratedValue(strategy = GenerationType.AUTO)
val id: Long,
#ManyToMany #JoinTable(
name = "author_book",
joinColumns = [JoinColumn(name = "book_id")],
inverseJoinColumns = [(JoinColumn(name = "author_id"))])
val author: Set<Author> = emptySet(),
val title: String,
val label: String,
val publisher: String
)
I have a basic Main:
#SpringBootApplication
open class Spring5webappApplication {
companion object {
#JvmStatic
fun main(args: Array<String>) {
SpringApplication.run(Spring5webappApplication::class.java, *args)
}
}
}
But when I boot, I get a bit error stack.
Could you give me some clue on this? I googled the errors but the answers are too unrelated. Thanks.
You have a typo in your code.
The attribute in book is called author instead of authors.
So this is the correct code.
val authors: Set<Author> = emptySet(),
Always look at the last exception in the stacktrace
Caused by: org.hibernate.AnnotationException:
mappedBy reference an unknown target entity property:
guru.springframework.spring5webapp.model.Book.authors in guru.springframework.spring5webapp.model.Author.books

Resources