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

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

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>

Spring Boot Validation is not working with javax.validation

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

#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>

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

How do I fix this Spring Boot entity relationship Error "creating bean with name 'entityManagerFactory' Unable to map collection"?

I am trying to create a secure login and I'm doing this by assigning a user to a role which will determine what kind of access they can have. My code has no errors but when I try to run the server I get the following error (my server will not even start):
"Error creating bean with name 'entityManagerFactory' Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Unable to map collection com.model.User.roles"
This is my role class:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class Role {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
public Role() {
}
public Role(String name) {
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;
}
#Override
public String toString() {
return "Role{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
This is part of my User class:
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.persistence.*;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
#Entity
#EntityListeners(AuditingEntityListener.class)
#Table(uniqueConstraints = #UniqueConstraint(columnNames = "emailAddress"))
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long userId;
//#NotBlank
#OneToMany(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
public List<Subject> subject;
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(
name = "users_roles",
joinColumns = #JoinColumn(
name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(
name = "role_id", referencedColumnName = "id"))
public Collection<Role> roles;
This is my POM file (I know it is all over the place):
<?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>com.finalYearProject</groupId>
<artifactId>student-life</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<!-- upgrade to thymeleaf version 3 -->
<thymeleaf.version>3.0.8.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
<thymeleaf-extras-springsecurity4.version>3.0.2.RELEASE</thymeleaf-extras-springsecurity4.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>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.2.1</version>
</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-security</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</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>
UPDATE
This is what I changed in the Role class to fix the problem:
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(
name = "users_roles",
joinColumns = #JoinColumn(
name = "user_userId", referencedColumnName = "userId"),
inverseJoinColumns = #JoinColumn(
name = "role_id", referencedColumnName = "id"))
The reference Column in the User entity is wrong.
You have defined:
private Long userId;
So the user table has a PK with the name user_id and the mapping must be:
#JoinTable(
name = "users_roles",
joinColumns = #JoinColumn(
name = "user_id", referencedColumnName = "user_id"),
inverseJoinColumns = #JoinColumn(
name = "role_id", referencedColumnName = "id"))
public Collection roles;
Try to define a collection of Users in the Role class
#ManyToMany(mappedBy = "roles")
private Collection<User> users;

Resources