org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL via JDBC Statement in SpringBoot with h2 and JPA - spring

While running spring boot with h2 database and JPA i am getting below error.
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL via JDBC Statement
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
at org.hibernate.tool.schema.internal.SchemaCreatorImpl.applySqlString(SchemaCreatorImpl.java:440) [hibernate-core-5.2.17.Final.jar:5.2.17.Final]
It is caused due to below one
Caused by: org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "CREATE TABLE EXCHANGE_VALUE (ID INTEGER NOT NULL, CONVERSION_MULTIPLE DECIMAL(19,2), FROM[*] VARCHAR(255), PORT INTEGER NOT NULL, TO VARCHAR(255), PRIMARY KEY (ID)) "; expected "identifier"; SQL statement:
create table exchange_value (id integer not null, conversion_multiple decimal(19,2), from varchar(255), port integer not null, to varchar(255), primary key (id)) [42001-197]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:357) ~[h2-1.4.197.jar:1.4.197]
at org.h2.message.DbException.getSyntaxError(DbException.java:217) ~[h2-1.4.197.jar:1.4.197]
My hibernate class
import java.math.BigDecimal;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="Exchange_Value")
public class ExchangeValue {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
private String from;
private String to;
private BigDecimal conversionMultiple;
private int port;
public ExchangeValue() {
}
public ExchangeValue(String from, String to, BigDecimal conversionMultiple) {
super();
// this.id = id;
this.from = from;
this.to = to;
this.conversionMultiple = conversionMultiple;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
application.properties is below
spring.application.name=currency-exchange-service
server.port=8000
spring.jpa.hibernate.ddl-auto= create-drop
Just want to know as to what i am missing in the code tried adding spring.jpa.hibernate.ddl-auto= create-drop but it did not helped.

#shubh.. Your Entity Field names are matching with SQL reserved keywords,
So try to change the field names otherwise use name attribute with #Column Annotation (which gives alias names to the DATABASE)
#Column(name="valueFrom")
private String from;
#Column(name="valueTo")
private String to;
private BigDecimal conversionMultiple;
private int port;

Your Entity Field name from was matched with database reserved word from,
change the field name to another, or add a #Column annotation on that field.
Like:
...
#Column(name = "_from")
private String from;
...

I faced the same issue. I did the mistake in giving the schema name in mysql database.
In spring.properties -> (spring boot application)
spring.datasource.url=jdbc:mysql://localhost:3306/db_microservice
Here instead of "db_microservice" I Have given the name as "db-microservice". So don't use "-". And this solved my issue.

#ganesh045's response isnt actually true because hibernate's table creation query works like this: CREATE TABLE <your_table> 'password' for example to each of your attributes. Adding the `` to the attribute will make SQL read it NOT as reserved keyword. It also does the same when it queries for your select clauses inside JpaRepository. It will make a call such as this: SELECT 'attribute' FROM <your_table>. Your problem is most likely that you specified your schema name as kebab-case or anything which is not camelCase and snake_case. Also, with this approach you can have a table called User with attribute's username and password which actually also are MYSQL reserved keywords.

Adding to others observation, I got the same error when a column name contains hyphen.
Error
#Column(name = "COST-CENTER")
private String costCenter;
Fixed
#Column(name = "COST_CENTER")
private String costCenter;

in my problem, database name was 'user'. that's why was giving a error. I changed database name, bug fixed.

Related

Error while testing with H2 database with Reactive Spring boot

I am using Reactive Spring boot to create a REST API and while the API works perfectly (I have tested it with postman), I also need to write some Unit tests and for the Unit tests I need to use a seperate in-memory database for it. I am using H2 database for testing and a hosted Postgres DB for the actual application and while my application entities are being loaded successfully in the postgres DB, None of my tests are passing as I receieve the following error:
Failed to execute SQL script statement #1 of class path resource [data.sql]: CREATE TABLE IF NOT EXISTS full_connection ( id BIGINT PRIMARY KEY , aa TEXT NOT NULL, fip TEXT NOT NULL, status TEXT, created_on TIMESTAMP, created_by TEXT, last_updated_on TIMESTAMP, last_updated_by TEXT ); nested exception is java.lang.ClassCastException: class java.lang.Long cannot be cast to class java.lang.Integer (java.lang.Long and java.lang.Integer are in module java.base of loader 'bootstrap')
I am assuming the error is being thrown because of the id paramater which has the datatype BIGINT which the official documentation of H2 says is mapped to java.long.Long.
Here's my entity:
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Builder
#ToString
#Table
public class FullConnection {
#Id
#Column(name = "id")
private Long id;
#Column(name = "AA", nullable = false)
private String aa;
#Column(name = "FIP", nullable = false)
private String fip;
private String status;
private LocalDateTime createdOn;
private String createdBy;
private LocalDateTime lastUpdatedOn;
private String lastUpdatedBy;
}
Here's how I am initializing the data:
#Bean
ConnectionFactoryInitializer initializer(#Qualifier("connectionFactory") ConnectionFactory connectionFactory) {
ConnectionFactoryInitializer initializer = new ConnectionFactoryInitializer();
initializer.setConnectionFactory(connectionFactory);
ResourceDatabasePopulator resource =
new ResourceDatabasePopulator(new ClassPathResource(dataInitializerName));
initializer.setDatabasePopulator(resource);
return initializer;
}
where it's reading the dataInitializerName string from application-test.yaml and is being read correctly, the script (for testing)(the script for prod and testing are different) is:
CREATE TABLE IF NOT EXISTS full_connection (
id BIGINT PRIMARY KEY ,
aa TEXT NOT NULL,
fip TEXT NOT NULL,
status TEXT,
created_on TIMESTAMP,
created_by TEXT,
last_updated_on TIMESTAMP,
last_updated_by TEXT
);
Here: https://www.h2database.com/html/datatypes.html#bigint_type it clearly states that BIGINT is mapped to java.long.Long, then why is it trying to cast it to int? Or is it regarding some other field?
I had a similar problem. Explicitly defining the version for the dependency r2dbc-h2 in pom.xml is causing the problem. I removed the version so that springboot will automatically use the compatible version of r2dbc-h2, and then the problem resolved.

How to fix another Repeated column in Mapping error?

I'm getting below error while running entities who dont have any key column in table. But I guess we cant create jpa entity without key column, so I have to set all cols as key to make it work.
In my table, there is not key and all cols are nullable. This is something I cant control
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity:
com.supmarket.entity.MyTable column: dimDate
(should be mapped with insert="false" update="false")
I've below entity
#Entity
public class MyTable{
#EmbeddedId
private MyTableId
private String region;
private Date dimDate;
private String loc;
}
#Entity
public class MyTableId implements Serializable{
private String region;
private Date dimDate;
private String loc;
}
Since, I dont have any primary key col in table, so I made all cols as composite key. But while running am getting above mentioned error.
May I know please, why its happening and how it can be fixed ?

Heroku shows Whitelabel Error Page but not on localhost

I have a Spring boot application with PostgreSQL. The app run very well on localhost with all the data from the PostgreSQL. I have successful upload the app to Heroku and migrated the database to Heroku PostgreSQL. The problem is when I click some of the links that retrieve data from PostgreSQL shows a White Error page. But on localhost every thing works fine.
Below is the Controller that link to the White Error Page.
#Controller
public class MahubiriController {
#Autowired
private MisaleRepository misaleRepository;
#GetMapping("/masomo/somolaleo")
public String masomoAngalia(Model model){
model.addAttribute("masomoYote", misaleRepository.findAllOrderByDateDesc() );
return "masomo";
} }
Below is the repository
#Repository
#Transactional
public interface MisaleRepository extends JpaRepository <Misale, String> {
#Query(value ="SELECT * FROM misale ORDER BY date DESC" , nativeQuery = true)
public List<Misale> findAllOrderByDateDesc();
}
Below is the Entity for the particular object
#Entity
#Table(name = "misale")
public class Misale {
#Id
#Column(name ="date")
private String date;
#Lob
#Column(name ="first_reading", columnDefinition="text")
private String firstReading;
#Lob
#Column(name ="second_reading", columnDefinition="text")
private String secondReading;
// Constructors, getter and setters
}
Below is the Query used to create the particular table on Postgresql
CREATE TABLE misale(date VARCHAR(20) NOT NULL PRIMARY KEY,
first_reading TEXT NOT NULL,
second_reading TEXT,gospel TEXT NOT NULL);
What could possibly be wrong on Heroku to lead to a White Error Page and not on a local host.
Update :
After implementing the Exception handling as suggested by # krishnkant jaiswal, I receive message "Unable to access lob str…le to access lob stream" as below.
timestamp "2021-04-03T01:26:43.791+00:00"
message "Unable to access lob stream; nested exception is org.hibernate.HibernateException: Unable to access lob stream"
details "uri=/masomo/somolaleo"
With the help of Exception handling and a long research, On my side it shows that you cannot use
#Lob and #Column(columnDefinition="text")
So I had to remove #Lob and leave #Column(columnDefinition="text")
#Column(columnDefinition="text")
Now I cloud retrieve the data from PostgreSQL without error.
Hope it might help someone else in future.

#Id annotation Causing duplication in list

I am using Hibernate for calling Stored procedure
Response returned by Stored procedure
receiverId fcmId source
1234 xyz android
45678 abc web
9876 fgh android
1234 ygh ios
Hibernet #EntityClass
#Entity
public class receieverDetails {
#Id
#Column(name="receiverId")
private String receiverUserId;
#Column(name="fcmId")
private String fcmIds;
private String source;
}
I am getting List of receiverDetails from database
if List contain duplicate receiverId as show is above response, 1st one is replacing the 4th details
Code for Binding
ProcedureCall procedureCall1 =
session.createStoredProcedureCall(Strings.StoredProcedureNames.GET_RECEIVER_INFO_OF_SPONSORED_MESSAGE,receieverDetails.class);
Output output1 = procedureCall1.getOutputs().getCurrent();
if(output1.isResultSet()) {
List<receieverDetails> receievers = ((ResultSetOutput) output1).getResultList();
}
i think this is causing by #Id annotation in the entity class, Because it is happening with same receiverIds only
Kindly Help me on this
In your code by providing the #Id annotation to the column receiverId, you are telling the code that this field is to be used as the primary key for the table.So, when fetching the data the issue occurs as there are duplicate values in the table for this column. Either you need to set the primary key correctly, or make this column as primary key in table and correct your code.
If you are using the same entity class to persist data and make column receiverId primary key then try using the below :
#Entity
public class receieverDetails {
#Id
#Column(name="receiverId",unique=true,nullable = false)
#GeneratedValue(strategy = GenerationType.AUTO)
private String receiverUserId;
#Column(name="fcmId")
private String fcmIds;
private String source;
}
unique=true in #Column is a shortcut for #UniqueConstraint(columnNames = {"receiverId"} and other particular constraints.The #GeneratedValue annotation is to configure the way of increment of the specified column(field).
or if the primary key of the table is some other field in table please correct the code to reflect the same.

Spring MVC - loading data

I have filled database and one entity which uses 2 tables like this:
#Entity
#Table(name="Product")
#SecondaryTable(name="B")
public class Product {
#Id
#GeneratedValue
private int idProduct;
#Column(name="name")
private String name;
#Column(table="B",name="aaaa")
private String aaa;
#Column(table="B",name="bbbb")
private String bbbb;
When I'm loading data from database table B is cleared, why?
I tried to change value in hibernate.hbm2ddl.auto from "create-drop" to "update" but I have an error like this:
"Can not set int field com.packt.webstore.domain.Product.bbbb to null value".
I need to load and write data to database so which value shoud I set and how to fix this error?
EDIT: When I set #Column(name="bbb", nullable=true) is the same error.

Resources