Kotlin, SpringBoot (JPA) transactional persistence issue for multiple repositories - spring-boot

I'm having an issue where I'm unable to persist multiple entities to their respective repositories. WHAT AM I DOING WRONG??? I'm able to persist to the first entity, but not to the second one. Why would this be?
HelperClass:
#Component
class Helper #Autowired constructor(
private val requestRepository: RequestRepository,
private val exchangeRateRepository: ExchangeRateRepository,
private val exchangeRateResultRepository: ExchangeRateResultRepository,
private val responseRepository: ResponseRepository
) {
fun processClientExchangeRateResponses(base: String, listSymbols: List<String>, clientResponses: List<ClientExchangeRateResponse>) {
requestRepository.save(Request("Test", "Test"))
responseRepository.save(Response(10.0, "Test", 12, 12, "Hello"))
}
}
The RequestEntity:
#Entity
#Table(name = "requests")
class Request(
#Column(name = "base", updatable = false, nullable = false)
private val base: String,
#Column(name = "requestObject", updatable = false, nullable = false)
private val requestObject: String
) {
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
#GenericGenerator(name = "native", strategy = "native")
#Column(name = "id", updatable = false, nullable = false)
val id: Long = 0
#CreationTimestamp
#Column(name = "created_at", nullable = false, columnDefinition = "DATETIME")
private val createdAt: ZonedDateTime? = getCurrentDateTime()
#CreationTimestamp
#Column(name = "updated_at", nullable = false, columnDefinition = "DATETIME")
private val updatedAt: ZonedDateTime? = getCurrentDateTime()
private fun getCurrentDateTime(): ZonedDateTime? {
return ZonedDateTime.now()
}
}
Response Entity:
#Entity
#Table(name = "responses")
class Response(
private val responseTime: Double,
private val currencyType: String,
private val exchangeId: Long,
private val requestId: Long,
private val responseObject: String
) {
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
#GenericGenerator(name = "native", strategy = "native")
#Column(name = "id", updatable = false, nullable = false)
val id: Long = 0
#CreationTimestamp
#Column(name = "created_at", nullable = false, columnDefinition = "DATETIME")
private val createdAt: ZonedDateTime? = getCurrentDateTime()
#CreationTimestamp
#Column(name = "updated_at", nullable = false, columnDefinition = "DATETIME")
private val updatedAt: ZonedDateTime? = getCurrentDateTime()
}
RequestRepository
#Repository
interface RequestRepository : JpaRepository<Request, Long>
ResponseRepository
#Repository
interface ResponseRepository : JpaRepository<Response, Long>
MainClass:
#EnableScheduling
#SpringBootApplication
class RatesApplication
fun main(args: Array<String>) {
runApplication<RatesApplication>(*args)
}
POM 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 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.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>globee</groupId>
<artifactId>rates</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>rates</name>
<description>Rates</description>
<repositories>
<repository>
<id>jcenter</id>
<url>https://jcenter.bintray.com/</url>
</repository>
</repositories>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
<maven.test.plugin.version>2.22.2</maven.test.plugin.version>
<kotlin.version>1.3.72</kotlin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>
<!--
Encountered some problems with this maven dependency. See the following two links for this solution
https://github.com/ascclemens/khttp and
https://khttp.readthedocs.io/en/latest/user/install.html#jitpack –>
-->
<dependency>
<groupId>khttp</groupId>
<artifactId>khttp</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.liquibase/liquibase-core -->
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>1.9.5</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>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</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>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<mainClass>globee.RatesApplication</mainClass>
</configuration>
</execution>
</executions>
</plugin>
<!-- https://mvnrepository.com/artifact/org.liquibase/liquibase-maven-plugin -->
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.10.2</version>
<configuration>
<propertyFileWillOverride>true</propertyFileWillOverride>
<propertyFile>src/main/resources/liquibase.properties</propertyFile>
</configuration>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<configuration>
<args>
<arg>-Xjsr305=strict</arg>
</args>
<compilerPlugins>
<plugin>spring</plugin>
</compilerPlugins>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>

The underlying Hibernate layer might effect your save here. Usually entities will not be written to DB unless you call commit or flush.
There is another method which writes the entities to DB immediately. It is called saveAndFlush. Maybe you should consider using this method in case you'd like to persist it immediately.
Maybe this article might clarify the difference: https://www.baeldung.com/spring-data-jpa-save-saveandflush

Related

New H2 version breaks liquibase

New version of H2 seems to have broken liquibase and JPA
<?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.6.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.h2test</groupId>
<artifactId>h2test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>h2test</name>
<description>h2test</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>4.7.1</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.210</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</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>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.properties
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
classes:
package com.h2test.h2test.domain;
import lombok.Data;
import javax.persistence.*;
#Entity
#Data
public class Person {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column
private String firstName;
#Column
private String lastName;
}
package com.h2test.h2test.repository;
import com.h2test.h2test.domain.Person;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface PersonRepository extends JpaRepository<Person, Long> {
}
#RestController
public class SomethingController {
#Autowired
private PersonRepository personRepository;
#GetMapping
public String test() {
Person person = new Person();
person.setFirstName("first name");
person.setLastName("last name");
personRepository.save(person);
return "hello";
}
}
Liquibase file:
databaseChangeLog:
- changeSet:
id: createTable-example
author: liquibase-docs
changes:
- createTable:
tableName: person
columns:
- column:
name: id
type: int
autoIncrement: true
constraints:
primaryKey: true
nullable: false
- column:
name: first_name
type: varchar(50)
- column:
name: last_name
type: varchar(50)
constraints:
nullable: false
When triggering the REST ENDPOINT localhost:8080 that creates and saves the Person entity I get the following error:
org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: NULL not allowed for column "ID"; SQL statement:
insert into person (id, first_name, last_name) values (null, ?, ?) [23502-202]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:508) ~[h2-2.0.202.jar:2.0.202]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477) ~[h2-2.0.202.jar:2.0.202]
This seems to only happen in the newer versions of H2. Any help is appreciated
Version 2.6.3 of spring-boot-starter-data-jpa has org.hibernate:hibernate-core:5.6.4.Final in its dependencies. This version doesn't support H2 2.x.y. You need to use 5.6.5:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.6.5.Final</version>
</dependency>
Also something is wrong with your classpath. You have H2 2.1.210 in dependencies, but exception in your question has error code 23502-202, it means it was produced by H2 2.0.202, you shouldn't use this outdated version, Hibernate ORM may have some problems with it.

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>

Kotlin SpringBoot and JPA - How to create relations OneToOne?

I am trying to create a relation OneToOne between two entities and always get the error (or very similar, Error creating bean with name 'entityManagerFactory' always):
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 org.hibernate.AnnotationException: Unknown mappedBy in: com.moises.kotlinstoreapi.model.Image.product, referenced property unknown: com.moises.kotlinstoreapi.model.Product.images
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1803) ~[spring-beans-5.2.1.RELEASE.jar:5.2.1.RELEASE]
...
[spring-boot-devtools-2.2.1.RELEASE.jar:2.2.1.RELEASE]
Caused by: org.hibernate.AnnotationException: Unknown mappedBy in: com.moises.kotlinstoreapi.model.Image.product, referenced property unknown: com.moises.kotlinstoreapi.model.Product.images
at org.hibernate.cfg.OneToOneSecondPass.doSecondPass(OneToOneSecondPass.java:169) ~[hibernate-core-5.4.8.Final.jar:5.4.8.Final]
I can create without problems the tables if I don't put the relations.
My code:
package com.moises.kotlinstoreapi.model
import com.fasterxml.jackson.annotation.JsonManagedReference
import javax.persistence.*
import javax.validation.constraints.NotBlank
#Entity
#Table(name="images")
data class Image (
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0,
val alt: String = "",
#NotBlank
val src: String = "",
val tite: String = "",
/**
* Relations
*
*/
//#OneToOne(mappedBy="images")
#OneToOne(mappedBy = "images", cascade = [(CascadeType.ALL)], fetch= FetchType.EAGER)
#JsonManagedReference
val product: Product = Product()
)
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 = "",
#NotBlank
val description: String = "",
#NotEmpty
var price: Double = 999.99,
#NotNull
var created_at: LocalDateTime = LocalDateTime.now(),
var update_at: LocalDateTime? = null,
/**
* Relations
*
*/
//#OneToOne(mappedBy="products", cascade = arrayOf(CascadeType.ALL))
//#JoinColumn(name = "id")
#OneToOne(cascade = [(CascadeType.ALL)], fetch= FetchType.EAGER)
#JoinColumn(name = "image_id")
#JsonManagedReference
val image: Image? = null
//#OneToOne(mappedBy="products", orphanRemoval=true, cascade=arrayOf(CascadeType.PERSIST))
//private val image: Image?
//#OneToOne(cascade = arrayOf(CascadeType.ALL))
//#JoinColumn(name = "purchase_line_id")
//val purchaseLine: PurchaseLine ?= 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>
you had wrong mappedBy value in Image - mappedBy = "images" it should be "image":
#OneToOne(mappedBy = "image", cascade = [(CascadeType.ALL)], fetch= FetchType.EAGER)
#JsonManagedReference
val product: Product = Product()
because Product has field image:
#JsonManagedReference
val image: Image? = null

Rest template getForObject() mapping only camel case fields

Having a rest web service that returns the below xml response.
Person>
<ttId>1408</ttId>
<FirstName>RAJ</FirstName>
<NationalityValue>INDIAN</NationalityValue>
<Sex>Male</Sex>
</Person>
This is the dto
import java.io.Serializable;
import java.util.Date;
public class PersonInfoDto implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Long ttId;
private String NationalityValue;
private String Sex;
private String FirstName;
//getters and setters
}
Using Spring Boot, When I try to consume using code it returns only one value(which is in camel case). Do I need to add any Naming strategy to make it work ?
String uri = apiPath;
RestTemplate restTemplate = new RestTemplate();
PersonInfoDto personInfoDto = restTemplate.getForObject(uri, PersonInfoDto.class);
//Here the object will contain only one value
ttId = 1408
rest values are returns null.
Is there any dependency is required for this ?
This is pom 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>msa</groupId>
<artifactId>MQA</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<name>MQA</name>
<description>MQA project</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.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>
<orika-core.version>1.4.6</orika-core.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-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- Oracle JDBC driver -->
<!-- https://mvnrepository.com/artifact/com.oracle/ojdbc14 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- Orika -->
<dependency>
<groupId>ma.glasnost.orika</groupId>
<artifactId>orika-core</artifactId>
<version>${orika-core.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
You should use #XmlElement. Try this
public class PersonInfoDto implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Long ttId;
#XmlElement(name = "NationalityValue")
private String nationalityValue;
#XmlElement(name = "Sex")
private String sex;
#XmlElement(name = "FirstName")
private String firstName;
//getters and setters
}
Another option is to write custom Http Message Converter. Have a look at this http://www.baeldung.com/spring-httpmessageconverter-rest
Removed the below entry from the pom.xml. It worked.
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>

Error creating bean with the name localContainerEntityManagerFactorryBean defined in the class path resource hibernateconfig.class

I'm getting the Error creating bean with the name localContainerEntityManagerFactorryBean defined in the class path resource hibernateconfig.class. nested exception is javax.persistence.persistenceException:unable to build hibernate session factory: A foreign key referring organizer from events has the wrong no of column, should be 2.
My pom file is
<?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.EventToday</groupId>
<artifactId>EventToday</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>EventToday</name>
<description>projects for events</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.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>
<springframework.version>4.0.6.RELEASE</springframework.version>
<hibernate.version>4.3.6.Final</hibernate.version>
<mysql.version>5.1.31</mysql.version>
<joda-time.version>2.3</joda-time.version>
<testng.version>6.9.4</testng.version>
<mockito.version>1.10.19</mockito.version>
<h2.version>1.4.187</h2.version>
<dbunit.version>2.2</dbunit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</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-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<exclusions>
<exclusion>
<groupId>org.hibernate</groupId>
<artifactId>ejb3-persistence</artifactId>
</exclusion>
<exclusion>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
</exclusion>
<exclusion>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<!-- jsr303 validation -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.0.2.GA</version>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<!-- Joda-Time -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<!-- To map JodaTime with database type -->
<dependency>
<groupId>org.jadira.usertype</groupId>
<artifactId>usertype.core</artifactId>
<version>3.0.0.CR1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<warName>EventToday</warName>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
<compilerArgs>
<arg>-Aopenjpa.metamodel=true</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>
and hibernate configuration
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories("com.EventToday.event.repository")
#ComponentScan({ "com.EventToday.event" })
#PropertySource(value = { "classpath:application.properties" })
public class hibernateconfig {
#Autowired
private Environment environment;
#Bean
public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.MYSQL);
//vendorAdapter.setGenerateDdl(generateDDL);
vendorAdapter.setShowSql(true);
LocalContainerEntityManagerFactoryBean beanFactory = new LocalContainerEntityManagerFactoryBean();
beanFactory.setJpaVendorAdapter(vendorAdapter);
beanFactory.setPackagesToScan("com.EventToday.event.model");
beanFactory.setDataSource(dataSource());
//beanFactory.afterPropertiesSet();
beanFactory.setJpaProperties(hibernateProperties());
return beanFactory;
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("spring.datasource.driverClassName"));
dataSource.setUrl(environment.getRequiredProperty("spring.datasource.url"));
dataSource.setSchema(environment.getRequiredProperty("spring.datasource.schema"));
dataSource.setUsername(environment.getRequiredProperty("spring.datasource.username"));
dataSource.setPassword(environment.getRequiredProperty("spring.datasource.password"));
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("spring.jpa.properties.hibernate.dialect", environment.getRequiredProperty("spring.jpa.properties.hibernate.dialect"));
properties.put("spring.jpa.show_sql", environment.getRequiredProperty("spring.jpa.show-sql"));
properties.put("spring.jpa.properties.hibernate.format_sql", environment.getRequiredProperty("spring.jpa.properties.hibernate.format_sql"));
return properties;
}
#Bean
public EntityManagerFactory entityManagerFactory(){
return localContainerEntityManagerFactoryBean().getObject();
}
#Bean
public EntityManager entityManager(){
return entityManagerFactory().createEntityManager();
}
#Bean
PlatformTransactionManager transactionManager(){
JpaTransactionManager manager = new JpaTransactionManager();
manager.setEntityManagerFactory(entityManagerFactory());
return manager;
}
#Bean
public HibernateExceptionTranslator hibernateExceptionTranslator(){
return new HibernateExceptionTranslator();
}
}
organizer
#Entity
#Table(name="organizer")
public class Organizer extends BaseEntity{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int roid;
#Column(name="orgNname", nullable=false)
private String organizerName;
#Column(name = "org_contact", nullable = false)
private String orgTelephone;
#Column(name = "org_altcontact", nullable = false)
private String orgContact;
#Column(name = "org_mail_address", nullable = false)
private String mailAddress;
#Column(name = "org_address", nullable = false)
private String orgAddress;
#OneToMany(mappedBy = "organizer")
private Set<events> evts;
public Set<events> getEvts() {
return evts;
}
public void setEvts(Set<events> evts) {
this.evts = evts;
}
public Organizer() {
}
//getters and setters
}
#events
#Entity
#Table(name="event")
public class events extends BaseEntity{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#ManyToOne
#JoinColumn(name = "roid")
private Organizer organizer;
public events() {
}
#Column(name = "event_name", nullable = false)
private String eventname;
#Column(name = "event_date", nullable = false)
#DateTimeFormat(pattern="dd/MM/yyyy")
#Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate date;
#NotNull
#Digits(integer=8, fraction=2)
#Column(name = "ticket_price", nullable = false)
private BigDecimal price;
#Column(name="event_location", nullable=false)
private String location;
#Column(name="happening_city", nullable=false)
private String Address;
#Column(name="contact_no", nullable=false)
private String contact_no;
#Column(name="alt_contact_no", nullable=false)
private String alternate_contact;
#Column(name="mail_address")
private String mail_address;
//getters and setters
}

Resources