How can i setup Spring Boot with two datasources (MapRepository and H2 JPARepository)? - spring-boot

I'm trying to set up a spring boot project with two datasources.
First datasource would be a H2 Database and second a MapRepository.
Both repositories would share the same entity.
I could manage to setup a project with two H2 databases, but when I try to setup a MapRepository instead of the second H2 datasource I get the following error:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.0)
2021-01-12 10:57:16.610 INFO 26672 --- [ main] ch.getonline.springtestapp.App : Starting App using Java 15.0.1 on nbbetina1 with PID 26672 (C:\Users\BetinaHiestand\eclipse20-workspace\spring-test-app\target\classes started by BetinaHiestand in C:\Users\BetinaHiestand\eclipse20-workspace\spring-test-app)
2021-01-12 10:57:16.612 INFO 26672 --- [ main] ch.getonline.springtestapp.App : The following profiles are active: dev
2021-01-12 10:57:17.070 INFO 26672 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2021-01-12 10:57:17.070 INFO 26672 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Map repositories in DEFAULT mode.
2021-01-12 10:57:17.092 INFO 26672 --- [ main] .RepositoryConfigurationExtensionSupport : Spring Data Map - Could not safely identify store assignment for repository candidate interface ch.getonline.springtestapp.storage.repositories.map.MapRepository. If you want this repository to be a Map repository, consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository.
2021-01-12 10:57:17.092 INFO 26672 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 15 ms. Found 0 Map repository interfaces.
2021-01-12 10:57:17.094 INFO 26672 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2021-01-12 10:57:17.094 INFO 26672 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2021-01-12 10:57:17.111 INFO 26672 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 14 ms. Found 1 JPA repository interfaces.
2021-01-12 10:57:17.654 INFO 26672 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-01-12 10:57:17.661 INFO 26672 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-01-12 10:57:17.661 INFO 26672 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.39]
2021-01-12 10:57:17.758 INFO 26672 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-01-12 10:57:17.758 INFO 26672 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1105 ms
2021-01-12 10:57:17.976 INFO 26672 --- [ main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/dbadmin'. Database available at 'jdbc:h2:mem:db1dev'
2021-01-12 10:57:18.058 INFO 26672 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2021-01-12 10:57:18.099 INFO 26672 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.4.23.Final
2021-01-12 10:57:18.198 INFO 26672 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2021-01-12 10:57:18.324 INFO 26672 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
Hibernate:
drop table if exists "BasicEntity" CASCADE
Hibernate:
create table "BasicEntity" (
"DNA" binary not null,
"id" varchar(255),
"type" varchar(255),
primary key ("DNA")
)
2021-01-12 10:57:18.759 INFO 26672 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2021-01-12 10:57:18.765 INFO 26672 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2021-01-12 10:57:18.787 INFO 26672 --- [ main] ch.getonline.springtestapp.App : SpringTestApplication is starting...
2021-01-12 10:57:18.931 WARN 26672 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'appContext': Unsatisfied dependency expressed through field 'entityStorage'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'entityStorageHandler' defined in file [C:\Users\BetinaHiestand\eclipse20-workspace\spring-test-app\target\classes\ch\getonline\springtestapp\storage\handlers\EntityStorageHandler.class]: Unsatisfied dependency expressed through constructor parameter 2; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'ch.getonline.springtestapp.storage.repositories.map.MapRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2021-01-12 10:57:18.931 INFO 26672 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2021-01-12 10:57:18.933 INFO 26672 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2021-01-12 10:57:18.944 INFO 26672 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-01-12 10:57:18.956 ERROR 26672 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 2 of constructor in ch.getonline.springtestapp.storage.handlers.EntityStorageHandler required a bean of type 'ch.getonline.springtestapp.storage.repositories.map.MapRepository' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'ch.getonline.springtestapp.storage.repositories.map.MapRepository' in your configuration.
I already tried to add the ComponentScan and add a repository annotation to the MapRepository, but couldn't figure out why no bean was created for it. Both repositories are in seperate packages which are set as basePackages for the EnableMapRepositories/EnableJpaRepositories annotation. For the SQLRepository I created a configuration class with the driver properties etc. I am not sure if something like this would also be needed for the MapRepositories and couldn't find helpful documentation about it.
I am not really experienced with Spring Boot therefore the first question would be if its possible to have a setup like this? And if yes how am I supposed to configure it?
Application start:
#SpringBootApplication
#ComponentScan (basePackages = {"ch.getonline.springtestapp"})
#EntityScan("ch.getonline.springtestapp.entity.types")
#EnableMapRepositories(basePackages = "ch.getonline.springtestapp.storage.repositories.map")
#EnableJpaRepositories(basePackages = "ch.getonline.springtestapp.storage.repositories.sql", entityManagerFactoryRef = "sqlDatabaseEntityManager", transactionManagerRef = "sqlDatabaseTransactionManager")
public class App {
// Logger setup (Per class)
private static final Logger log = LoggerFactory.getLogger(App.class);
/*
* Application start
*/
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(App.class, args);
System.out.println("App context in main: " + ctx.getDisplayName());
}
MapRepository:
package ch.getonline.springtestapp.storage.repositories.map;
import org.springframework.stereotype.Repository;
import ch.getonline.springtestapp.storage.repositories.EntityRepository;
#Repository("mapRepository")
public interface MapRepository extends EntityRepository {
}
EntityRepository:
package ch.getonline.springtestapp.storage.repositories;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.NoRepositoryBean;
import ch.getonline.springtestapp.entity.types.BasicEntity;
#NoRepositoryBean
public interface EntityRepository extends CrudRepository<BasicEntity, Long>{
//Entity findByUuid(UUID id);
}
StorageHandler in which I tried to access both repositories:
package ch.getonline.springtestapp.storage.handlers;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import ch.getonline.springtestapp.AppContext;
import ch.getonline.springtestapp.entity.attribute.Attribute;
import ch.getonline.springtestapp.entity.types.BasicEntity;
import ch.getonline.springtestapp.storage.StorageHandler;
import ch.getonline.springtestapp.storage.repositories.EntityRepository;
import ch.getonline.springtestapp.storage.repositories.map.MapRepository;
import ch.getonline.springtestapp.storage.repositories.sql.SQLRepository;
/** Entity Storage
* <br>
*
* - Coordinates saving, loading, updating of Entities over different Repositories
*
*
* #author sigi
*
*/
#Component
public class EntityStorageHandler implements StorageHandler<BasicEntity, Long> {
// Logger
private static final Logger log = LoggerFactory.getLogger(EntityStorageHandler.class);
private final AppContext app;
private final Map<String, EntityRepository> repos;
EntityStorageHandler(AppContext app, SQLRepository sqlRepo, MapRepository mapRepo) {
this.app = app;
this.repos = new HashMap<String, EntityRepository>();
this.repos.put("sql", sqlRepo);
this.repos.put("map", mapRepo);
}
//StorageHandler start hook
public void run(String... args) throws Exception {
//Print all configs for the key app in the config
StringBuilder appConfig = new StringBuilder();
for(Entry<String, Object> entry : this.app.getConfig().entrySet()) {
appConfig.append("\nkey: " + entry.getKey() + " value: " + entry.getValue());
}
log.info(appConfig.toString());
//Write demo Entity into db
BasicEntity e1 = new BasicEntity();
e1.setId("1");
e1.setType("Type1");
this.repos.get("sql").save(e1);
BasicEntity e2 = new BasicEntity();
e2.setId("2");
e2.setType("Type2");
this.repos.get("sql").save(e2);
BasicEntity e3 = new BasicEntity();
e3.setId("3");
e3.setType("Type3");
this.repos.get("map").save(e2);
}
}
BasicEntity:
package ch.getonline.springtestapp.entity.types;
import java.util.UUID;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import org.springframework.data.keyvalue.annotation.KeySpace;
import ch.getonline.springtestapp.entity.GenericEntity;
/**
* Basic Entity Implementation
*
* #author sigi
*
*/
#Entity
#KeySpace("basicEntities")
public class BasicEntity extends GenericEntity {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
UUID DNA;
}
SQLConfiguration:
package ch.getonline.springtestapp.configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
import java.util.HashMap;
#Configuration
public class SQLConfiguration {
#Autowired
private Environment env;
public SQLConfiguration() {
super();
}
#Primary
#Bean
public LocalContainerEntityManagerFactoryBean sqlDatabaseEntityManager() {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(sqlDataSource());
em.setPackagesToScan("ch.getonline.springtestapp.entity.types");
final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
final HashMap<String, Object> properties = new HashMap<String, Object>();
properties.put("hibernate.hbm2ddl.auto", env.getProperty("spring.jpa.hibernate.ddl-auto"));
properties.put("hibernate.dialect", env.getProperty("spring.jpa.database-platform"));
properties.put("hibernate.jdbc.batch_size", env.getProperty("spring.jpa.properties.hibernate.jdbc.batch_size"));
properties.put("hibernate.order_inserts", env.getProperty("spring.jpa.properties.hibernate.order_inserts"));
properties.put("hibernate.order_updates", env.getProperty("spring.jpa.properties.hibernate.order_updates"));
properties.put("hibernate.jdbc.batch_versioned_data", env.getProperty("spring.jpa.properties.hibernate.jdbc.batch_versioned_data"));
properties.put("hibernate.generate_statistics", env.getProperty("spring.jpa.properties.hibernate.generate_statistics"));
properties.put("hibernate.id.new_generator_mappings", env.getProperty("spring.jpa.properties.hibernate.id.new_generator_mappings"));
properties.put("hhibernate.cache.use_second_level_cache", env.getProperty("spring.jpa.properties.hibernate.cache.use_second_level_cache"));
properties.put("hibernate.globally_quoted_identifiers", env.getProperty("spring.jpa.properties.hibernate.globally_quoted_identifiers"));
properties.put("hibernate.format_sql", env.getProperty("spring.jpa.properties.hibernate.format_sql"));
properties.put("hibernate.show_sql", env.getProperty("spring.jpa.properties.hibernate.show_sql"));
properties.put("hibernate.use_sql_comments", env.getProperty("spring.jpa.properties.hibernate.use_sql_comments"));
properties.put("hibernate.type", env.getProperty("spring.jpa.properties.hibernate.type"));
properties.put("hibernate.naming.physical-strategy", env.getProperty("spring.jpa.hibernate.naming.physical-strategy"));
em.setJpaPropertyMap(properties);
return em;
}
#Primary
#Bean
public DataSource sqlDataSource() {
final DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("spring.datasource.driverClassName"));
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));
dataSource.setPassword(env.getProperty("spring.datasource.password"));
return dataSource;
}
#Primary
#Bean
public PlatformTransactionManager sqlDatabaseTransactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(sqlDatabaseEntityManager().getObject());
return transactionManager;
}
}
SQLRepository
package ch.getonline.springtestapp.storage.repositories.sql;
import ch.getonline.springtestapp.storage.repositories.EntityRepository;
public interface SQLRepository extends EntityRepository {
}
application.yml
#Debug mode
debug: false
#External config
spring:
#Basic setup
profiles.active: dev
config:
import: optional:classpath:config/app.properties, optional:classpath:config/config.yml
#Localization
messages:
basename: config.i18n.messages
#db
h2:
console:
path: /dbadmin
enabled: true
settings:
web-allow-others: true
datasource:
username: inmemory
password: inmemory
driverClassName: org.h2.Driver
port: 8080
#jpa
jpa:
hibernate:
ddl-auto: create
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
properties:
hibernate:
id:
new_generator_mappings: true
cache:
use_second_level_cache: true
order_inserts: true
order_updates: true
globally_quoted_identifiers: true
generate_statistics: false
show_sql: true
format_sql: true
use_sql_comments: true
type: trace
jdbc:
batch_size: 500
batch_versioned_data: false
tmp:
use_jdbc_metadata_defaults: false
database-platform: org.hibernate.dialect.H2Dialect

As written in my comment, it's quite unusual to use two different datasources with one spring boot service. But here are cases where this might be necessary, and here is how to achieve it in a clean way:
Keep in mind, my answer is mostly taken from that Baeldung tutorial
Consider having a datasource like this:
spring.datasource.jdbcUrl = [url]
spring.datasource.username = [username]
spring.datasource.password = [password]
Now, we want to add a second one, preferably with the same syntax:
spring.second-datasource.jdbcUrl = [url]
spring.second-datasource.username = [username]
spring.second-datasource.password = [password]
To use both configurations simoultanously, we just create two configuration classes with a Datasource Bean - pay attention to the prefix annotation:
#Configuration
#PropertySource({"classpath:persistence-multiple-db-boot.properties"})
#EnableJpaRepositories(
basePackages = "com.baeldung.multipledb.dao.user",
entityManagerFactoryRef = "userEntityManager",
transactionManagerRef = "userTransactionManager")
public class PersistenceUserAutoConfiguration {
#Primary
#Bean
#ConfigurationProperties(prefix="spring.datasource")
public DataSource userDataSource() {
return DataSourceBuilder.create().build();
}
// userEntityManager bean
// userTransactionManager bean
}
#Configuration
#PropertySource({"classpath:persistence-multiple-db-boot.properties"})
#EnableJpaRepositories(
basePackages = "com.baeldung.multipledb.dao.product",
entityManagerFactoryRef = "productEntityManager",
transactionManagerRef = "productTransactionManager")
public class PersistenceProductAutoConfiguration {
#Bean
#ConfigurationProperties(prefix="spring.second-datasource")
public DataSource productDataSource() {
return DataSourceBuilder.create().build();
}
// productEntityManager bean
// productTransactionManager bean
}
You could imo just create one configuration class and provide both beans in that one.
For more information see Spring JPA – Multiple Databases

Related

Unable to insert values into h2 database table

I am trying to run a code to get the details of user with a given id.
This is my code.
package com.in28minutes.database.databasedemo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.in28minutes.database.databasedemo.jpa.PersonJpaRepository;
#SpringBootApplication
public class JpaDemoApplication implements CommandLineRunner {
private Logger logger = LoggerFactory.getLogger(this.getClass());
#Autowired
PersonJpaRepository repository;
public static void main(String[] args) {
SpringApplication.run(JpaDemoApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
logger.info("User id 10001 -> {}", repository.findById(10001));
}
}
This is my repository:
package com.in28minutes.database.databasedemo.jpa;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
import org.springframework.stereotype.Repository;
import com.in28minutes.database.databasedemo.entity.Person;
#Repository
#Transactional
public class PersonJpaRepository {
//connect to the database
#PersistenceContext
EntityManager entityManager;
public Person findById(int id) {
return entityManager.find(Person.class, id);
}
}
package com.in28minutes.database.databasedemo.entity;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
#Entity
public class Person {
#Id
#GeneratedValue
private int id;
private String name;
private String location;
private Date birthDate;
public Person() {
}
public Person(int id, String name, String location, Date birthDate) {
super();
this.id = id;
this.name = name;
this.location = location;
this.birthDate = birthDate;
}
public Person(String name, String location, Date birthDate) {
super();
this.name = name;
this.location = location;
this.birthDate = birthDate;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
#Override
public String toString() {
return String.format("\nPerson [id=%s, name=%s, location=%s, birthDate=%s]", id, name, location, birthDate);
}
}
And this is my schema
create table person
(
id integer not null,
name varchar(255) not null,
location varchar(255),
birth_date timestamp,
primary key(id)
);
INSERT INTO PERSON (ID, NAME, LOCATION, BIRTH_DATE )
VALUES(10001, 'Ranga', 'Hyderabad',sysdate());
INSERT INTO PERSON (ID, NAME, LOCATION, BIRTH_DATE )
VALUES(10002, 'James', 'New York',sysdate());
INSERT INTO PERSON (ID, NAME, LOCATION, BIRTH_DATE )
VALUES(10003, 'Pieter', 'Amsterdam',sysdate());
I also have spring.h2.console.enabled=true in my application.properties.
2021-10-17 04:17:53.745 INFO 17096 --- [ main] c.i.d.databasedemo.JpaDemoApplication : Starting JpaDemoApplication using Java 16.0.2 on DESKTOP-Q0GM1GU with PID 17096 (C:\Users\HP\Desktop\database-demo\target\classes started by HP in C:\Users\HP\Desktop\database-demo)
2021-10-17 04:17:53.750 INFO 17096 --- [ main] c.i.d.databasedemo.JpaDemoApplication : No active profile set, falling back to default profiles: default
2021-10-17 04:17:55.170 INFO 17096 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2021-10-17 04:17:55.210 INFO 17096 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 14 ms. Found 0 JPA repository interfaces.
2021-10-17 04:17:57.110 INFO 17096 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-10-17 04:17:57.130 INFO 17096 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-10-17 04:17:57.130 INFO 17096 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.54]
2021-10-17 04:17:57.417 INFO 17096 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-10-17 04:17:57.418 INFO 17096 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3557 ms
2021-10-17 04:17:57.512 INFO 17096 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2021-10-17 04:17:57.924 INFO 17096 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2021-10-17 04:17:57.968 INFO 17096 --- [ main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:0af42eb0-d2fc-45af-ad68-57b087b53fc0'
2021-10-17 04:17:58.592 INFO 17096 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2021-10-17 04:17:58.733 INFO 17096 --- [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.6.0.Final
2021-10-17 04:17:59.180 INFO 17096 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2021-10-17 04:17:59.662 INFO 17096 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
Hibernate: drop table if exists person CASCADE
Hibernate: drop sequence if exists hibernate_sequence
Hibernate: create sequence hibernate_sequence start with 1 increment by 1
Hibernate: create table person (id integer not null, birth_date timestamp, location varchar(255), name varchar(255), primary key (id))
2021-10-17 04:18:01.342 INFO 17096 --- [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2021-10-17 04:18:01.368 INFO 17096 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2021-10-17 04:18:01.656 WARN 17096 --- [ main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2021-10-17 04:18:02.194 WARN 17096 --- [ main] o.s.w.s.r.ResourceHttpRequestHandler : Locations list is empty. No resources will be served unless a custom ResourceResolver is configured as an alternative to PathResourceResolver.
2021-10-17 04:18:02.550 INFO 17096 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2021-10-17 04:18:02.568 INFO 17096 --- [ main] c.i.d.databasedemo.JpaDemoApplication : Started JpaDemoApplication in 9.623 seconds (JVM running for 10.727)
Hibernate: select person0_.id as id1_0_0_, person0_.birth_date as birth_da2_0_0_, person0_.location as location3_0_0_, person0_.name as name4_0_0_ from person person0_ where person0_.id=?
2021-10-17 04:18:02.770 INFO 17096 --- [ main] ication$$EnhancerBySpringCGLIB$$6f304a0c : User id 10001 -> null
However, in my result, I am getting the value back as null. Also, I know that I should be getting an error that the table PERSON already exists and it that it should not be declared in the schema, but that is not the case.
After checking the h2 database, I see that none of the values are inserted.
You can try adding spring.jpa.hibernate.ddl-auto=create to your property file. You can check this question here in stackoverflow or from the documentation.

Illegal use of #Table in a subclass of a SINGLE_TABLE hierarchy

I'm a newbie in Spring. I try to create a project with SOLID techniques but was faced with that error. Inheritance does not work in my application. Why inheritance does not work properly? Is inheritance allowed in Spring?
Text of Error:
2021-06-23 23:54:08.928 INFO 12984 --- [ restartedMain] hrms.northwind.NorthwindApplication : Starting NorthwindApplication using Java 15.0.2 on DESKTOP-87K40S0 with PID 12984 (C:\Users\90553\Desktop\Eclipse Projects\HRMS Project\target\classes started by 90553 in C:\Users\90553\Desktop\Eclipse Projects\HRMS Project)
2021-06-23 23:54:08.929 INFO 12984 --- [ restartedMain] hrms.northwind.NorthwindApplication : No active profile set, falling back to default profiles: default
2021-06-23 23:54:08.978 INFO 12984 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2021-06-23 23:54:08.978 INFO 12984 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2021-06-23 23:54:09.465 INFO 12984 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2021-06-23 23:54:09.512 INFO 12984 --- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 40 ms. Found 2 JPA repository interfaces.
2021-06-23 23:54:10.040 INFO 12984 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-06-23 23:54:10.052 INFO 12984 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-06-23 23:54:10.052 INFO 12984 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.46]
2021-06-23 23:54:10.130 INFO 12984 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-06-23 23:54:10.130 INFO 12984 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1152 ms
2021-06-23 23:54:10.203 INFO 12984 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2021-06-23 23:54:10.367 INFO 12984 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2021-06-23 23:54:10.458 INFO 12984 --- [ restartedMain] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2021-06-23 23:54:10.502 INFO 12984 --- [ restartedMain] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.4.32.Final
2021-06-23 23:54:10.619 INFO 12984 --- [ restartedMain] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2021-06-23 23:54:10.721 INFO 12984 --- [ restartedMain] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
2021-06-23 23:54:11.047 WARN 12984 --- [ restartedMain] org.hibernate.cfg.AnnotationBinder : HHH000139: Illegal use of #Table in a subclass of a SINGLE_TABLE hierarchy: hrms.northwind.entities.concretes.Employer
2021-06-23 23:54:11.049 WARN 12984 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: 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 java.lang.ClassCastException: class org.hibernate.mapping.SingleTableSubclass cannot be cast to class org.hibernate.mapping.RootClass (org.hibernate.mapping.SingleTableSubclass and org.hibernate.mapping.RootClass are in unnamed module of loader 'app')
2021-06-23 23:54:11.050 INFO 12984 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2021-06-23 23:54:11.053 INFO 12984 --- [ restartedMain] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
2021-06-23 23:54:11.057 INFO 12984 --- [ restartedMain] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2021-06-23 23:54:11.066 INFO 12984 --- [ restartedMain] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-06-23 23:54:11.084 ERROR 12984 --- [ restartedMain] o.s.boot.SpringApplication : Application run failed
Employer Class:
package hrms.northwind.entities.concretes;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Data;
#Entity(name="Employers")
#Table(name="Employers")
#Data
public class Employer extends Person {
#Id
#GeneratedValue
#Column(name="employer_id")
private int employerId;
#Column(name="company_name")
private String company_name;
#Column(name="website")
private String website;
#Column(name="phone_number")
private String phone_number;
#Column(name="password")
private String password;
public Employer(int personId, String name, String surname, String email, int employerId, String company_name, String website,
String phone_number, String password) {
super(personId, name, surname, email);
this.employerId = employerId;
this.company_name = company_name;
this.website = website;
this.phone_number = phone_number;
this.password = password;
}
}
Employer Dao:
package hrms.northwind.dataAccess.abstracts;
import org.springframework.data.jpa.repository.JpaRepository;
import hrms.northwind.entities.concretes.Employer;
public interface EmployerDao extends JpaRepository<Employer,Integer>{
}
Employer Service:
package hrms.northwind.business.abstracts;
import java.util.List;
import org.springframework.stereotype.Service;
import hrms.northwind.entities.concretes.Employer;
#Service
public interface EmployerService {
List<Employer> getAll();
}
Employer Controller:
package hrms.northwind.api.controllers;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import hrms.northwind.business.abstracts.EmployerService;
import hrms.northwind.entities.concretes.Employer;
#RestController
#RequestMapping("/api/employers")
public class EmployerController {
private EmployerService employerService;
#Autowired
public EmployerController(EmployerService employerService) {
super();
this.employerService = employerService;
}
#GetMapping("/getall")
public List<Employer> getAll(){
return this.employerService.getAll();
}
}
Employer Table:
Employer Table
Any help?
Maybe is late for this answer
I think the problem comes from #Table. That annotation is optional when you want to specify an entity.
You could find better documented answer here
You can add this to your Employer class.
#Inheritance(strategy = InheritanceType.JOINED)
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
#PrimaryKeyJoinColumn(name="employer_id",referencedColumnName = "person_id")

Springboot : failed while scanning for beans

I am trying to understand a concept in springboot.
I have project structure as mentioned below. There are two packages and I have one class in each package.
src/main/java
> com.emerald.paymentengine
ApplicationRun.java
> com.emerald.paymentengine.config
DataSourceDbConfig.java
When I am trying to run the ApplicationRun.java following above structure, I am getting below error :
Error:
2020-08-19 01:33:08.673 INFO 30128 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-08-19 01:33:08.673 INFO 30128 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.37]
2020-08-19 01:33:08.749 INFO 30128 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-08-19 01:33:08.750 INFO 30128 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 657 ms
2020-08-19 01:33:08.779 WARN 30128 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'applicationRun': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.emerlad.paymentengine.config.DataSourceDbConfig' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2020-08-19 01:33:08.781 INFO 30128 --- [ restartedMain] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2020-08-19 01:33:08.791 INFO 30128 --- [ restartedMain] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-08-19 01:33:08.883 ERROR 30128 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.emerald.paymentengine.ApplicationRun required a bean of type 'com.emerlad.paymentengine.config.DataSourceDbConfig' that could not be found.
Action:
Consider defining a bean of type 'com.emerlad.paymentengine.config.DataSourceDbConfig' in your configuration.
But when I moved DataSourceDbConfig.java in the same package as mentioned below, it's running and I am getting below output :
src/main/java
> com.emerald.paymentengine
ApplicationRun.java
DataSourceDbConfig.java
Output :
2020-08-19 01:37:24.726 INFO 34364 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-08-19 01:37:24.726 INFO 34364 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.37]
2020-08-19 01:37:24.810 INFO 34364 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-08-19 01:37:24.810 INFO 34364 --- [ restartedMain] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 722 ms
2020-08-19 01:37:24.849 INFO 34364 --- [ restartedMain] f.a.AutowiredAnnotationBeanPostProcessor : Autowired annotation is not supported on static fields: static com.emerald.paymentengine.DataSourceDbConfig com.emerald.paymentengine.ApplicationRun.dbConfig
Connection established !!
2020-08-19 01:37:24.981 INFO 34364 --- [ restartedMain] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-08-19 01:37:25.116 INFO 34364 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2020-08-19 01:37:25.140 INFO 34364 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8082 (http) with context path ''
2020-08-19 01:37:25.148 INFO 34364 --- [ restartedMain] c.emerald.paymentengine.ApplicationRun : Started ApplicationRun in 1.335 seconds (JVM running for 2.406)
I was thinking #SpringBootApplication will automatically scan the main and subpackages and will be able to pick the required bean. How can I make it work by placing Config.java file in different package as mentioned in the very first scenario?
Code :
ApplicationRun.java
package com.emerald.paymentengine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class ApplicationRun {
#Autowired
static
DataSourceDbConfig dbConfig;
public ApplicationRun(DataSourceDbConfig dbConfig){
ApplicationRun.dbConfig = dbConfig ;
}
public static void main(String[] args) {
SpringApplication.run(ApplicationRun.class, args);
dbConfig.dataSource();
}
}
DataSourceDbConfig.java
package com.emerlad.paymentengine.config;;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import oracle.jdbc.pool.OracleDataSource;
import java.sql.SQLException;
import javax.sql.DataSource;
#Component
#Configuration
#ConfigurationProperties("spring.datasource")
public class DataSourceDbConfig {
#Value("${spring.datasource.url}")
private String dbUrl;
#Value("${spring.datasource.username}")
private String dbUser;
#Value("${spring.datasource.secure}")
private String dbPasswrd;
#Bean
public DataSource dataSource() {
OracleDataSource dataSource = null;
try {
dataSource = new OracleDataSource();
dataSource.setUser(dbUser);
dataSource.setPassword(dbPasswrd);
dataSource.setURL(dbUrl);
System.out.println("Connection established !!");
} catch (SQLException e) {
System.out.println("An issue occured while establishing connection !!");
e.printStackTrace();
}
return dataSource;
}
}
I'll be honest, I do not understand what it is that you want to accomplish, but this is how to get the DataSource bean in your main method:
ApplicationRun.java:
package com.emerald.paymentengine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.emerlad.paymentengine.config.DataSourceDbConfig;
import org.springframework.context.annotation.Import;
import javax.sql.DataSource;
#SpringBootApplication
#Import(DataSourceDbConfig.class)
public class ApplicationRun {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(ApplicationRun.class, args);
DataSource dataSource = context.getBean(DataSource.class)
}
}
DataSourceDbConfig.java:
package com.emerlad.paymentengine.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import oracle.jdbc.pool.OracleDataSource;
import java.sql.SQLException;
import javax.sql.DataSource;
#Configuration
#ConfigurationProperties("spring.datasource")
public class DataSourceDbConfig {
#Value("${spring.datasource.url}")
private String dbUrl;
#Value("${spring.datasource.username}")
private String dbUser;
#Value("${spring.datasource.secure}")
private String dbPasswrd;
#Bean
public DataSource dataSource() {
OracleDataSource dataSource = null;
try {
dataSource = new OracleDataSource();
dataSource.setUser(dbUser);
dataSource.setPassword(dbPasswrd);
dataSource.setURL(dbUrl);
System.out.println("Connection established !!");
} catch (SQLException e) {
System.out.println("An issue occured while establishing connection !!");
e.printStackTrace();
}
return dataSource;
}
}
class DataSourceDbConfig - using #Configuration includes #Component, so you can get rid of it
class ApplicationRun - I would keep it simple and remove the DataSourceDbConfig
#SpringBootApplication
public class ApplicationRun {
public static void main(String[] args) {
ApplicationContext appContext = SpringApplication.run(ApplicationRun.class, args);
// Getting datasource from application context.
DataSource dataSource = appContext.getBean(DataSource.class);
}
}

Java Spring Boot Rest API 400 Bad Request

I am trying to make a async Rest API with Spring Boot.
The Rest API receives http requests that have a json body with one value "zahl", then it extracts that value, opens a socket and sends a tcp request with that number to a loadbalacer, that divides the Requests on different servers.
They all make the same and calculate wheter the given number is a prime or not.
If it is, it returns a String for example: "(89) is prime: (true)" or "(10) is prime: false".
The result goes back over the loadbalancer to the Rest API and finally to the client.
That's how it should works.
But for most requests I get Bad Request 400. Sometimes it works fine.
400 Bad Request
Therefore I tried to do the calculation directly instead of opening a socket and it works perfectly.
So the problem is the Socket right?
Here is my Code:
package javaRestApi;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
#SpringBootApplication
#RestController
public class MyRestController extends SpringBootServletInitializer {
private static Logger log = LoggerFactory.getLogger(MyRestController.class);
public static void main(String[] args) {
SpringApplication.run(MyRestController.class, args);
}
#Autowired
private AsyncService service;
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(MyRestController.class);
}
#PostMapping(value = "/api/request/json", consumes = MediaType.APPLICATION_JSON_VALUE)
public String jsonRequest(#RequestBody RequestModel body) throws IOException, Exception {
log.info("new Request");
CompletableFuture<String> result = service.isPrime(body.getZahl());
log.info("Result: " + result.get());
return result.get();
}
}
package javaRestApi;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#JsonIgnoreProperties(ignoreUnknown=true)
public class RequestModel {
private String zahl;
public void setZahl(String zahl) {
this.zahl=zahl;
}
public String getZahl() {
return zahl;
}
}
package javaRestApi;
import java.util.concurrent.Executor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
#Configuration
#EnableAsync
public class AsyncConfiguration {
#Bean(name = "asyncExecutor")
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("AsyncThread-");
executor.initialize();
return executor;
}
}
And finally the class where I create the Socket...
package javaRestApi;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.concurrent.CompletableFuture;
import javax.net.SocketFactory;
import java.net.Socket;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
#Service
public class AsyncService {
#Async("asyncExecutor")
public CompletableFuture<String> isPrime(String zahl) throws IOException, Exception {
//direct calcualtion
int z = Integer.parseInt(zahl);
if(prime(z))
return CompletableFuture.completedFuture("" + z + " is prime");
else
return CompletableFuture.completedFuture("" + z + " is no prime");
//with Tcp Connection
//return CompletableFuture.completedFuture("3"/*tcpClient(zahl)*/);
}
//local prime calculation
private static boolean prime(int zahl) {
for(int i = 2; i<zahl; i++) {
if(zahl % i == 0) {
return false;
}
}
return true;
}
// TCP connection to load balancer
private static String tcpClient(String zahl) throws IOException, Exception {
java.net.Socket socket = SocketFactory.getDefault().createSocket("localhost", 12345);
senden(socket, zahl);
return lesen(socket);
}
// send the value to Socket
static void senden(java.net.Socket socket, String zahl) throws IOException {
PrintWriter prwr = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
prwr.print(zahl);
prwr.flush();
}
// get the result from the socket
static String lesen(java.net.Socket socket) throws IOException {
int Buflength = 40;
BufferedReader bufR = new BufferedReader(new InputStreamReader(socket.getInputStream()));
char[] buf = new char[Buflength];
int anzZeichen = bufR.read(buf, 0, Buflength);
String retString = new String(buf, 0, anzZeichen);
return retString;
}
}
And here the Stacktrace.
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.1.RELEASE)
2020-06-26 20:22:36.106 INFO 71152 --- [ main] javaRestApi.MyRestController : Starting MyRestController on DESKTOP-FVOQ69M with PID 71152 (C:\Users\Fill07\Desktop\javaRestApi\target\classes started by Fill07 in C:\Users\Fill07\Desktop\javaRestApi)
2020-06-26 20:22:36.110 INFO 71152 --- [ main] javaRestApi.MyRestController : No active profile set, falling back to default profiles: default
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils (file:/C:/Users/Fill07/.m2/repository/org/springframework/spring-core/5.2.7.RELEASE/spring-core-5.2.7.RELEASE.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
2020-06-26 20:22:37.870 INFO 71152 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2020-06-26 20:22:37.884 INFO 71152 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-06-26 20:22:37.884 INFO 71152 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.36]
2020-06-26 20:22:38.213 INFO 71152 --- [ main] org.apache.jasper.servlet.TldScanner : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
2020-06-26 20:22:38.225 INFO 71152 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-06-26 20:22:38.225 INFO 71152 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2041 ms
2020-06-26 20:22:38.356 INFO 71152 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService
2020-06-26 20:22:38.358 INFO 71152 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'asyncExecutor'
2020-06-26 20:22:38.845 INFO 71152 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-06-26 20:22:38.860 INFO 71152 --- [ main] javaRestApi.MyRestController : Started MyRestController in 3.385 seconds (JVM running for 3.941)
2020-06-26 20:22:40.830 INFO 71152 --- [nio-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-06-26 20:22:40.830 INFO 71152 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-06-26 20:22:40.841 INFO 71152 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed initialization in 11 ms
2020-06-26 20:22:40.977 INFO 71152 --- [nio-8080-exec-2] javaRestApi.MyRestController : new Request
2020-06-26 20:22:41.013 INFO 71152 --- [nio-8080-exec-2] javaRestApi.MyRestController : Result: HTTP/1.1 400 Bad Request
Connection: cl
I don't understand what is wrong, i mean sometimes it works.
How can I fix it?
Is it maybe a problem with Tomcat?
Thanks for any advice.

Spring Boot controller required a bean of type 'org.dozer.Mapper' that could not be found

I've created a spring boot project and added
compile('net.sf.dozer:dozer:5.5.1')
to dependencies. But the class, org.dozer.Mapper, is not recognized by my app.
I run gradle clean, gradle buildDependents and gradle build.
But things did not changed.
What should I do ?
my build.gradle
buildscript {
ext {
springBootVersion = '2.0.0.RC1'
}
repositories {
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.everglowtrading'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
maven { url "https://repository.jboss.org/nexus/content/repositories/releases" }
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-aop')
compile('org.flywaydb:flyway-core')
compile('org.springframework.boot:spring-boot-starter-hateoas')
compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.1')
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-webflux')
compile('org.springframework.data:spring-data-commons')
compile('com.h2database:h2')
compile('net.sf.dozer:dozer:5.5.1')
runtime('org.springframework.boot:spring-boot-devtools')
runtime('com.h2database:h2')
compileOnly('org.projectlombok:lombok')
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('io.projectreactor:reactor-test')
}
The controller
package com.myproject.stock.controllers;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import javax.servlet.http.HttpServletResponse;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import com.myproject.stock.domain.model.Stock;
import com.myproject.stock.domain.repository.StockCriteria;
import com.myproject.stock.form.StockListForm;
import com.myproject.stock.service.StockService;
#RestController
public class StockController {
private static final int DEFAULT_PAGEABLE_SIZE = 5;
#Autowired
Mapper beanMapper;
#Autowired
StockService<Integer> stockService;
#Autowired
MessageSource msg;
#RequestMapping("/")
void index(HttpServletResponse response) throws IOException {
response.sendRedirect("/stock");
}
#RequestMapping("/stock")
public ModelAndView stock(ModelAndView mav) {
Stock stock = stockService.getItems(11);
List<Stock> stockList = stockService.getAllItems();
String message = msg.getMessage("stock.label", null, Locale.JAPAN);
mav.addObject("stock_id", stock.getId());
mav.addObject("stockList", stockList);
mav.addObject("message", message);
mav.addObject("stockBuildingName", stock.getBuilding_name());
mav.setViewName("stock/search/index");
return mav;
}
#RequestMapping("/stock/search")
public String index(#Validated StockListForm stockListForm
, BindingResult bindingResult
, Pageable pageable
, Model model) {
StockCriteria criteria = beanMapper.map(stockListForm, StockCriteria.class);
Page<Stock> page = stockService.findPageByCriteria(criteria, pageable);
model.addAttribute("page", page);
return "stock/search/index";
}
}
the error message
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.0.RC1)
2018-02-19 22:15:35.648 INFO 7950 --- [ restartedMain] c.e.wms.stock.WmsApplication : Starting WmsApplication on YatabeMBP.local with PID 7950 (/Users/ayatabe/dev/wms-stock/build/classes/java/main started by ayatabe in /Users/ayatabe/dev/wms-stock)
2018-02-19 22:15:35.648 INFO 7950 --- [ restartedMain] c.e.wms.stock.WmsApplication : No active profile set, falling back to default profiles: default
2018-02-19 22:15:35.695 INFO 7950 --- [ restartedMain] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#82f0a7d: startup date [Mon Feb 19 22:15:35 JST 2018]; root of context hierarchy
2018-02-19 22:15:36.772 INFO 7950 --- [ restartedMain] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$d86c709b] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-02-19 22:15:37.104 INFO 7950 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 9090 (http)
2018-02-19 22:15:37.114 INFO 7950 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2018-02-19 22:15:37.114 INFO 7950 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.27
2018-02-19 22:15:37.127 INFO 7950 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/ayatabe/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.]
2018-02-19 22:15:37.209 INFO 7950 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-02-19 22:15:37.209 INFO 7950 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1517 ms
2018-02-19 22:15:37.369 INFO 7950 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
2018-02-19 22:15:37.371 INFO 7950 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet webServlet mapped to [/h2console/*]
2018-02-19 22:15:37.374 INFO 7950 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-02-19 22:15:37.374 INFO 7950 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-02-19 22:15:37.374 INFO 7950 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-02-19 22:15:37.374 INFO 7950 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2018-02-19 22:15:37.415 WARN 7950 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'stockController': Unsatisfied dependency expressed through field 'beanMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.dozer.Mapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
2018-02-19 22:15:37.417 INFO 7950 --- [ restartedMain] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2018-02-19 22:15:37.434 INFO 7950 --- [ restartedMain] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-02-19 22:15:37.550 ERROR 7950 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field beanMapper in com.myproject.stock.controllers.StockController required a bean of type 'org.dozer.Mapper' that could not be found.
Action:
Consider defining a bean of type 'org.dozer.Mapper' in your configuration.
You haven't define a bean for org.dozer.Mapper type so Spring can't inject a proper instance to your controller class.
The simplest way to define this bean is to add following method to your main Spring application class:
#Bean
public Mapper mapper() {
return new DozerBeanMapper();
}
Alternatively you can put it in any #Configuration annotated class.
For those who might run into the same problem as me:
Add #MapperScan("yourMapperPath") at your spring boot main launch class. If the notation shows as red, reimport your mybatis-spring-boot-starter dependency:
Go to your project pom.xml > right click on the artifactId > Maven > Reimport
I thought I have imported the dependency days ago, but the project didn't.

Resources