How to write case sensitive column pojo in spring data JPA - mysql

We have a product which runs in mysql, oracle and sqlserver. We are writing one custom module which needs to access a customer table and retrieve data. We are writing it using spring data JPA.
For this we have Customer pojo as below and created a Repository.
Note that the columns are case sensitive. The POJO that works for oracle is as below,
import lombok.*;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Getter
#Setter
#ToString
#Table(name="customer")
public class Customer{
#Id
#Column(name="\"cxCifID\"")
private String cxCifID;
#Column(name="\"hostCustId\"")
private String hostCustId;
#Column(name="\"custMobile1\"")
private String custMobile1;
#Column(name="\"custEmail1\"")
private String custEmail1;
#Column(name="\"custName\"")
private String custName;
#Column(name="\"custMotherTongue\"")
private String custMotherTongue;
}
The same will not work in mysql and will give the error as below,
"Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"cxCifID" as cxcifid1_0_, customer0_."custEmail1" as custemai2_0_, customer0_."c' at line 1"
If i use the below POJO for mysql it works without error,
import lombok.*;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Getter
#Setter
#ToString
#Table(name="customer")
public class Customer{
#Id
#Column(name="cxCifID")
private String cxCifID;
#Column(name="hostCustId")
private String hostCustId;
#Column(name="custMobile1")
private String custMobile1;
#Column(name="custEmail1")
private String custEmail1;
#Column(name="custName")
private String custName;
#Column(name="custMotherTongue")
private String custMotherTongue;
}
The question is how can I create and use a single POJO which can be used in both the databases or in fact in all the databases? Please help

Related

Spring boot auto create table in mysql fail

I meet an following error, can not figure out. I suppose I can use Spring boot connect to mysql db. And it can create table auto. And this is connect to a docker container, not sure if this matters
spring.datasource.poolName=spring-jpa
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC&createDatabaseIfNotExist=true
spring.datasource.username=root
spring.datasource.password=1q2w3e4R
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
server.session.timeout=8640000
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.hibernate.use-new-id-generator-mappings=false
The error is:
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "create table subscription (id bigint not null auto_increment, consent bit, email varchar(255), first_name varchar(255), gender varchar(255), newsletter_id integer, primary key (id)) type=MyISAM" via JDBC Statement
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) ~[hibernate-core-5.4.27.Final.jar:5.4.27.Final]
....
Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'type=MyISAM' at line 1
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120) ~[mysql-connector-java-8.0.22.jar:8.0.22]
....
This is the subscription entity class:
import lombok.Getter;
import lombok.Setter;
import javax.annotation.Generated;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Getter
#Setter
#Entity
#Table
public class Subscription {
#Id
#GeneratedValue(strategy= GenerationType.AUTO)
private long id;
#Column
private String email;
#Column
private String firstName;
#Enumerated(EnumType.STRING)
#Column
private Gender gender;
#Column
private boolean consent;
#Column
private int newsletterId;
}
This is the Gender class
public enum Gender {
MALE, FEMALE
}
This is caused because type=MyISAM was deprecated since MySQL 4.x.
The property
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
Implies hibernate to use the initial Dialect.
Changing it to
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
Will generate SQL for MySQL 5.0+, with engine=MyISAM instead of type=MyISAM , similarly based on your MySQL version, change your dialect.
Example if you have MySQL 7 use org.hibernate.dialect.MySQL7Dialect

Field personRepositary in () required a bean of type () that could not be found

I am trying to run a spring developed web app and I'm getting the following error.
My folder structure is as follows.
Here is my PersonRepositary.java code which is inside the repositary folder.
package com.travelx.travelx.repositary;
import org.springframework.data.repository.CrudRepository;
import com.travelx.travelx.models.Person;
public interface PersonRepositary extends CrudRepository<Person, Integer> {
}
The RegisterController.java file which is in the controllers folder is ac follows.
package com.travelx.travelx.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.travelx.travelx.models.Person;
import com.travelx.travelx.repositary.PersonRepositary;
#RestController
#RequestMapping("register")
public class RegisterController {
#Autowired
private PersonRepositary personRepositary;
#PostMapping("login")
public String registerPerson(#RequestBody Person person) {
personRepositary.save(person);
return "You are Registered!";
}
}
And the TravelXApplication.java file which is in the controllers is below.
package com.travelx.travelx.controllers;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication
#ComponentScan
#EntityScan
#EnableJpaRepositories
public class TravelxApplication {
public static void main(String[] args) {
SpringApplication.run(TravelxApplication.class, args);
}
}
I'm trying to make a web page where a person can register to a site. Here, I'm using xampp as my platform to handle the back end. As shown in the image, the controllers, repositories and and models are implemented in separate folders. I'm new to Spring. So no matter how hard I to find what the problem is, I cant seem to find it. Can some one help me please?
--------------UPDATE------------------
I've moved my TravelXApplication.java to the com.travelx.travelx and now this error is gone.Spring works fine. However when I open my form, insert data and try to save it, the browser gives me the following error.
How do I solve it?
Your PersonRepositary is not registered as a bean in your Spring context. In practice, this means that Spring is not be able to inject it in your RegisterController.
I suspect that #EnableJpaRepositories, #EntityScan and #ComponentScan are unnecessary in your main application class and are actually causing Spring automatic configuration to be overridden. Try deleting these three annotations from TravelxApplication.
Here's the answer to why it should still work without annotations.
Update: just noticed that your TravelxApplication is located in the controllers package, but then it won't have visibility to your repository. Make sure to move your main class to the com.travelx.travelx package.

SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet

Error: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
I am working on CRUD using JPA in Spring Boot; and trying to insert data in MySQL table using JSP pages.BUT after submitting the form, Table automatically deletes from MySQL Database....
I have gone through all tutorial by searching the Error. I am following this example
student.java
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.GenerationType;
#Entity
#Table(name="student")
public class Student
{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="sname")
private String sname;
#Column(name="email")
private String email;
#Column(name="key1")
private String key1;
}
I expect that data should be enter into the mentioned table.
Whenever you face such type of error, while running Spring Boot + JPA CRUD Example, Just check once that you have defined ID field using AUTO_INCREMENT option or not.
I was having such type of Error because I did not require ID field. BUT Spring Boot Hibernate checks for Unique A_I ID field.
If you don't require ID field, then use and Your problem will be solved.

Jackson #JsonFormat changes time in date with 2hours back

I have strange problem with Dates - java.util.Date. In my database I have a row with a date like that:
It show it is 10:30 time. But when I create an REST api and go to the developer tools in Chrome I see that the time was changed with 2 hours, e.g:
In my application properties I added two things:
spring.jackson.date-format=yyyy-MM-dd'T'HH:mm:ss.SSSZ
spring.jackson.serialization.write-dates-as-timestamps: false
And my model class looks like (with #JsonFormat):
import java.util.Date; <- look I have java.util.Date, not Yoda.
import com.carwash.utils.JsonDateSerializer;
import com.carwash.utils.ReviewStatus;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Data;
#Data
public class ReservationModel {
private String code;
//#JsonSerialize(using=JsonDateSerializer.class)
#JsonFormat(pattern="yyyy-MM-dd HH:mm")
private Date date;

#RunWith(PowerMockRunner.class) is disallowed for this location

I am getting following error
The annotation #RunWith is disallowed for this location
I have following imports.
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
#RunWith(PowerMockRunner.class)
#PrepareForTest(QueryValidator.class)
#Test
public void testValidateIds2() { ... }
What is causing this and how can I get rid of this.
figured #RunWith(PowerMockRunner.class) is a class level annotation and needs to go on top of the class, not the method.