Spring 2.3.4.RELEASE, Mybatis.Spring.boot 2.1.3 : Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required - spring

I am using idea to build artifact based on a Mybatis demo project.
It is really a simple demo containing:
main class:
#MapperScan(basePackages = "thusca.testMybatis.mapper")
#SpringBootApplication()
public class SampleMybatisApplication{
public static void main(String[] args) {
SpringApplication.run(SampleMybatisApplication.class, args);
}
}
mapper:
#Mapper
public interface CityMapper {
#Select("SELECT * FROM CITY WHERE state = #{state}")
City findByState(#Param("state") String state);
}
model:
public class City implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String name;
private String state;
...
}
service:
#Service
public class mysqlService{
#Autowired
CityMapper mapper;
}
It runs correctly when I run it using GUI mode. However if I build artifact and run it using command java -jar xxx.jar. It always fails and reports error ava.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required.
I googled it and tried all solutions but no one worked.
here is my pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>testxxx</groupId>
<artifactId>testMybatis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>testMybatis</name>
<description>testxxx.testMybatis</description>
<properties>
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
</dependencies>
</project>
and application.properties
server.port=8083
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=xxxxxx
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.max-idle=10
spring.datasource.max-wait=1000
spring.datasource.min-idle=5
spring.datasource.initial-size=5
server.session.timeout=10
server.tomcat.uri-encoding=UTF-8
ps: for my project, only idea can be used to build artifact(jar), mvn command cannot be used.

Related

Error creating bean with name 'entityManagerFactory' defined in class path Springboot

Tried all possible solutions but can't resolve this error. The application is very basic. I have used MySQLDialect 8 as I use mysql version 8.0.22 but still the error persists. What shall be done to resolve this issue. This is the error that I am getting
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-07-08 20:28:36.746 ERROR 7660 --- [ main] 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 org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.springrest</groupId>
<artifactId>springrest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springrest</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
server.port=8050
#database configuration:mysql
spring.datasource.url=jdbc:mysql://localhost:3306/sampledb
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#Hibernate config
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect="org.hibernate.dialect,MySQL8Dialect"
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false
Course.java
#Entity
public class Course {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "<seq name in java in generator anno>")
#SequenceGenerator(name = "<seq name in java in generator anno>", sequenceName = "<seq name in db>", allocationSize = 1)
private int id;
private String title;
private String desc;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public Course() {
super();
}
public Course(int id, String title, String desc) {
super();
this.id = id;
this.title = title;
this.desc = desc;
}
}
I think you've made a typo and used "," instead of ".".
Try changing "org.hibernate.dialect,MySQL8Dialect" to "org.hibernate.dialect.MySQL8Dialect" in your configuration file.
Check if your database URL is correct and if your database is up and running. Also check if your username and password are correct.

How to use Spring's BackendIdConverter?

I have an entity named VendorProductMapping with embedded primary key. Hence I want to use BackendIdConverter to convert the embedded primary key to string and vice-versa.
I followed a few posts on stackoverflow and learnt that I need to use BackendIdConverter.
I created the following class:
public class VendorProductMappingIdConverter implements BackendIdConverter {
#Override
public Serializable fromRequestId(String id, Class<?> entityType) {
--
}
#Override
public String toRequestId(Serializable source, Class<?> entityType) {
--
}
#Override
public boolean supports(Class<?> type) {
--
}
}
The very first line gives me an error saying
Cannot resolve symbol 'BackendIdConverter'
Do I explicitly need to create a BackendIdConverter interface ?
Here is my pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 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.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>UI</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>UI</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-validation</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>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
EDIT:
Now that I've written a converter class, how do I use this ?
I need to send the primary key of VendorProductMapping class (i.e, VendorProductMappingPk) may be in an anchor tag. The error I see is
Failed to convert value of type 'java.lang.String' to required type 'com.example.UI.entity.VendorProductMappingPk'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.example.UI.entity.VendorProductMappingPk': no matching editors or conversion strategy found
BackendIdConverter is part of Spring Boot Data REST, so try adding the following dependency. However, I am not sure this is what you need for your case.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
I would say you need a JPA converter to achieve this:
#Converter
public class PersonNameConverter implements AttributeConverter<YourEmbeddedPrimaryKeyClass, String> {
#Override
public String convertToDatabaseColumn(YourEmbeddedPrimaryKeyClass id) {
// your conversion to String logic
}
#Override
public YourEmbeddedPrimaryKeyClass convertToEntityAttribute(String id) {
// your conversion to YourEmbeddedPrimaryKeyClass logic
}
}
Then you can configure this converter in your model:
#Entity
#IdClass(PK.class)
public class YourClass {
#Id
private YourEmbeddedPrimaryKeyClass id;
...
}
public class PK implements Serializable {
#Column(name = "MY_ID_FIELD")
#Convert(converter = IdConverter.class)
private YourEmbeddedPrimaryKeyClass id;
}
You can check additional details at https://www.baeldung.com/jpa-attribute-converters.

property read from application.properties returning null

I am new to springboot and i am trying to read the property value from the application.properties file in the location(src/main/resources). But it always return null. I need help for the same. Attaching the classes and property files.
Please note: I have tried different ways from "https://www.baeldung.com/properties-with-spring "How to access a value defined in the application.properties file in Spring Boot".
But this is not helping in getting the value from the application.properties file.
#SpringBootApplication
#EnableAutoConfiguration
#PropertySource("classpath:application.properties")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
SampleTest ap=new SampleTest();
System.out.println("+++++++++++++ "+ap.returnvalue());
}
#Configuration
#PropertySource("classpath:application.properties")
public class SampleTest {
#Value("${testValue}")
String value1;
public String returnvalue()
{
return value1;
}
}
application.properties file
testValue=Value from application
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 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>ReadValue</groupId>
<artifactId>com.read.vale</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>com.read.vale</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.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-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Try this:
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
SampleTest ap = ctx.getBean(SampleTest.class);
System.out.println("+++++++++++++ "+ap.returnvalue());
}

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>

Issue when testing Spring framework

I need to add unit testing to my Spring project. I'm currently using spring framework within JAX-RS, but I'm unable to test it.
My pom.xml is as follows:
<?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.zcd2</groupId>
<artifactId>helloworldapi</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.1.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-inmemory</artifactId>
<version>2.26</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.26</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.26</version>
<scope>test</scope>
</dependency>
</dependencies>
My java file:
#Path("/external-spring-hello")
public class ExternalSpringRequestResource {
#Autowired
private GreetingService greetingService;
#GET
#Produces(MediaType.TEXT_PLAIN)
public String getHello() {
return greetingService.getMessage();
}
}
And my test file is:
public class ExternalSpringRequestResourceTest extends JerseyTest {
#Override
protected Application configure() {
return new ResourceConfig(ExternalSpringRequestResource.class);
}
#Override
protected DeploymentContext configureDeployment() {
ResourceConfig config = new ResourceConfig(ExternalSpringRequestResource.class);
config.packages("com.trial");
return ServletDeploymentContext
.forServlet(new ServletContainer(config))
.addListener(ContextLoaderListener.class)
.contextParam("contextConfigLocation", "classpath:applicationContext.xml")
.build();
}
#Test
public void first() throws Exception {
final String response = target("/external-spring-hello").request().get(String.class);
Assert.assertEquals(response, "Hello");
}
}
However, I'm getting that error:
java.lang.NullPointerException
at org.glassfish.jersey.server.ApplicationConfigurator.createApplication(ApplicationConfigurator.java:131)
at org.glassfish.jersey.server.ApplicationConfigurator.init(ApplicationConfigurator.java:104)
at org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$0(ApplicationHandler.java:313)
at java.util.Arrays$ArrayList.forEach(Arrays.java:3880)
at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:313)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:282)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:257)
at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory$InMemoryTestContainer.<init>(InMemoryTestContainerFactory.java:78)
at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory$InMemoryTestContainer.<init>(InMemoryTestContainerFactory.java:64)
at org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory.create(InMemoryTestContainerFactory.java:112)
at org.glassfish.jersey.test.JerseyTest.createTestContainer(JerseyTest.java:278)
at org.glassfish.jersey.test.JerseyTest.setUp(JerseyTest.java:608)
It looks like an issue with jersey server library. How can I solve that?
Thanks a lot

Resources