I am developing a simple RESTfull service in Java Spring and using JDBCTemplate.
However, I am getting a run time error, which I don't understand. It complains about SPRING_SESSION table not existing, however I think Spring should be able to create necessary tables as needed.
application.properties:
spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=jdbc:mysql://localhost:3306/getfit?useSSL=false
spring.datasource.username=root
spring.datasource.password=***
Exception:
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [DELETE FROM SPRING_SESSION WHERE EXPIRY_TIME < ?]; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'getfit.SPRING_SESSION' doesn't exist
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:235) ~[spring-jdbc-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72) ~[spring-jdbc-5.0.4.RELEASE.jar:5.0.4.RELEASE]
Exception is triggered by some process attempting to delete record from table which doesn't exist.
Manually creating the table leads to more errors (not existing columns). Setting
hibernate.ddl-auto=update
also doesn't help.
Additionally, I have
modified MySQL configuration to allow upper case characters and this also did not help.
Interestingly enough, this issue happened after I formatted my OS and cloned project from github. Before everything was working fine.
Do you have any ideas what could go wrong? Let me know if you need me to show you some code.
Thanks for looking in to this :)
try to set the initialize-schema to always:
spring.session.jdbc.initialize-schema: always
Spring session creates a table to store sessions in the database. Since the required table doesn't exist it throws the error.
Here's a link you can refer
https://sivalabs.in/2018/02/session-management-using-spring-session-jdbc-datastore/
Related
I have a Spring Boot app that is configured to use JPA and its default-provider Hibernate. The app, in environment Non-Local, expects, and, through Oracle, is configured to connect to, an existing SQL DB, while the app, in environment Local, must, through H2, create it...embedded, in-memory, and private.
The DB utilizes one schema, as seen in this entity:
#Entity #Table(schema="foo",name="transactions")
Environment Local must, and is configured to, create (after first dropping any existing) tables and their schema. It is the creation, and dropping, of the latter - schema - that exhibits a problem:
Hibernate: drop table if exists foo.foo_transactions CASCADE
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "drop table if exists foo.foo_transactions CASCADE " via JDBC Statement
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Schema "FOO" not found; SQL statement: drop table if exists foo.foo_transactions CASCADE [90079-200]
...and a similar one (Schema not found) for CREATE.
So as to ensure no overlap, in the classpath, between H2 and Oracle, I, in the POM, separate them by build-profile (local and non-local):
<profile><id>local</id>...<dependencies><dependency>H2</dependency></dependencies>
<profile><id>non-local</id>...<dependences><dependency>Oracle</dependency></dependencies>
My relevant configuration of Spring Boot is:
# file application.properties
spring.datasource.url=jdbc:oracle:thin...
# file application-local.properties
# blankness of following value masks default configuration, in application.properties
spring.datasource.url=
spring.jpa.properties.javax.persistence.schema-generation.create-database-schemas=true
That JPA-property, javax.persistence.schema-generation.create-database-schemas, is supposed to do EXACTLY what I desire: create, in addition to tables, any internal schema. Yet, as shown in the aforementioned errors, it doesn't work!
Does H2, or the combination of H2, JPA-provider Hibernate, and Spring Boot, not honor it??? Or, have I miscoded/misconfigured something?
I don't want to get bogged down in the following (as the preceding question is my main concern), but for full disclosure...
P.S. If I remove the schema and build and run locally, everything works fine. But, the non-local (Production) flavor mandates that schema, so I must comply, and wish to do so also locally.
P.P.S. I am, indeed, aware of H2's directive 'INIT=CREATE SCHEMA IF NOT EXISTS foo' (to be applied to the datasource URL), and it, if used, does alleviate the problem. However, if I do use it (thereby having to explicitly supply a url, thereby conceding Spring Boot's very nice and full auto-configuration [of H2]), it causes another problem, which I need to avoid:
2022-08-29 15:43:27.494 WARN 15288 --- [on(5)-127.0.0.1] o.s.b.f.support.DisposableBeanAdapter: Invocation of destroy method failed on bean with name 'inMemoryDatabaseShutdownExecutor': org.h2.jdbc.JdbcSQLNonTransientConnectionException: Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) [90121-200]
P.P.P.S. Neither that recommendation (...;DB_CLOSE_ON_EXIT=FALSE) nor its sister (...;DB_CLOSE_DELAY=-1) nor their combination alleviate that problem (attempt to close an already-closed DB).
I've now figured it out - my relevant JPA-property, at least as far as Hibernate is concerned, was slightly wrong...
Whereas I used (as it had once worked for me in EclipseLink, lazily leading me to believe that it was generic to all JPA-providers)
javax.persistence.schema-generation.create-database-schemas
I should have used this
javax.persistence.create-database-schemas
I am using HSQLDB for JUnit Tests, the test data is provided by XML Files with dbUnit. Our application uses an Oracle DB in production.
In order to suppert Oracle-specific queries I have added the property sql.syntax_ora=true to the url like this:
db.url=jdbc:hsqldb:mem:unitdb;sql.syntax_ora=true
When I run my JUnit test I get the exception
org.hsqldb.HsqlException: The table data is read only
I have also tried to execute the query SET DATABASE SQL SYNTAX ORA TRUE;
but this gives me the same exception.
Please help me with this problem. Thanks!
I am surprised I haven't found an SO question that answers this. I am trying to connect a springboot/JPA application to an SQL Server on my local machine. I have the application setup so that it can connect to a database if it it exists, but if I change the JDBC URL to create the database if it doesn't exist then it fails. Here is what the properties look like when it fails.
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:sqlserver://localhost:1433;databaseName=testing;createDatabaseIfNotExist=true;
spring.datasource.username=hello
spring.datasource.password=Hello1234
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.database-platform=org.hibernate.dialect.SQLServer2008Dialect
spring.jpa.show-sql=true
Here is a snippet of the error I receive when starting the app:
com.microsoft.sqlserver.jdbc.SQLServerException: Login failed for user
'hello'. ClientConnectionId:971a3369-258b-4713-bddc-cda559b9fe94 at
com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:262)
~[mssql-jdbc-8.4.0.jre11.jar:na] at
com.microsoft.sqlserver.jdbc.TDSTokenHandle
If anybody has any thoughts as to how I can change this so the database is created if it does not exist I would be very thankful. Thanks in advnace.
I don't think a database can be created using JPA.
It has to be created manually or in some other ways, but JPA won't do that for you.
And it would be a bad practice as well to create the database using the application itself, and the use of same credentials.
Yes, definitely you can auto-create a database with JPA for that
spring.datasource.url=jdbc:sqlserver://localhost:1433;databaseName=testing;
createDatabaseIfNotExist=true;
line should be changed to:
spring.datasource.url=jdbc:sqlserver://localhost:1433
/testing?createDatabaseIfNotExist=true
In practice your application should never create your database so its not really a problem most of the time(Outside small databases like sqlite3). Different databases would handle this situation differently as well.
In your case I do not see this as a valid jdbc parameter in the documentation.
I would recommend creating the database in advance with a privileged user separate from your application user.
I have a Spring Boot 2 application with a mysql database running and wanted to add the Quartz scheduler. Configuration:
spring.quartz.job-store-type=jdbc
spring.quartz.jdbc.initialize-schema=always
spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false
But on start-up it doesn't create the database tables and fails when accessing the QRTZ_* tables. I debugged to get the cause which I found in ScriptUtils class called by Spring to execute the quartz script tables_mysql_innodv.sql. The exception is suppressed intentionally:
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 'DROP TABLE IF
EXISTS QRTZ_PAUSED_TRIGGER_GRPS; DROP TABLE IF EXISTS QRTZ_SCHEDUL' at
line 9
I cannot see any syntax error and when I execute the same script in MySQL Workbench directly then it runs fine, i.e. creates the tables etc.
The source of the executed start-up script is available here. Exception is encountered in this line. There is one observation that makes me confused: The code in the same method tries to split the SQL statements but only 2 statements are extracted - the first line # and the remaining script. Maybe this is the actual problem.
So, how can I fix this?
Version info:
Spring Boot 2.0.2.RELEASE
mysql:mysql-connector-java:5.1.46
org.quartz-scheduler:quartz:2.3.0
Add the following property to your configuration, to specify the comment character :
spring.quartz.jdbc.comment-prefix=#
In YAML configuration properties file, as suggest by Mouad EL Fakir I added:
quartz:
job-store-type: jdbc
jdbc:
initialize-schema: always
comment-prefix: '#'
There is a workaround:
Copy the script file tables_mysql_innodb.sql
to your resources folder main/resources/org/quartz/impl/jdbcjobstore/tables_mysql_innodb.sql. This will be picked up by spring boot instead of the original file.
Remove all comment lines at the start of the file. These are the problematic lines for parsing in Spring's ScriptUtils class.
the method 'ScriptUtils.containsSqlScriptDelimiters' can not resolve the scripts properly.
because the mysql scripts's comments contain some single quotes. you can replace the single quotes with blank.
I am working on a project using Spring Boot 1.5.2.RELEASE and have been tasked with adding database backed HTTP sessions.
So, I got this working in the 2.0.0.RELEASE easily enough and the application started and created the tables spring_session and spring_session_attributes
Here's the properties I added to the later version that got things working:
spring.session.store-type=jdbc
spring.session.jdbc.initialize-schema=ALWAYS
Looking at spring-boot 1.5.2.RELEASE it seems to use spring-session 1.3.0.RELEASE as the managed version so I found the docs here: https://docs.spring.io/spring-session/docs/1.3.0.RELEASE/reference/html5/guides/httpsession-jdbc.html
No matter what I try I get the following error:
Whitelabel Error Page This application has no explicit mapping for
/error, so you are seeing this as a fallback. Tue Mar 20 14:02:06 GMT
2018 There was an unexpected error (type=Internal Server Error,
status=500). PreparedStatementCallback; bad SQL grammar [SELECT
S.SESSION_ID, S.CREATION_TIME, S.LAST_ACCESS_TIME,
S.MAX_INACTIVE_INTERVAL, SA.ATTRIBUTE_NAME, SA.ATTRIBUTE_BYTES FROM
SPRING_SESSION S LEFT OUTER JOIN SPRING_SESSION_ATTRIBUTES SA ON
S.SESSION_ID = SA.SESSION_ID WHERE S.SESSION_ID = ?]; nested exception
is org.postgresql.util.PSQLException: ERROR: relation "spring_session"
does not exist Position: 127
Here is my application.properties (I am trying to get the tables to appear in my PostgreSQL database)- these tables should be created for me automatically, right?
spring.datasource.url=jdbc:postgresql://localhost:5432/sandbox
spring.datasource.password=sandbox
spring.datasource.username=sandbox
spring.thymeleaf.cache=false
spring.template.cache=false
spring.session.store-type=jdbc
spring.session.jdbc.initializer.enabled=true
Can you try after adding this
spring.session.jdbc.table-name=SPRING_SESSION
Unfortunately I couldn’t get the tables to create automatically so I dug through the spring-session jar file for the schema and created them manually. Good news is that sessions are now persisted in my database!