How to set MySQL ANSI_QUOTES mode via MySQL Java Connector? - java

I have a Scala (Java) Play Web Application where I wrap database identifiers with ANSI double-quotes in queries e.g.
select *
from "account"
where "deleted" is null
order by "account_name"
This is necessary because I use among others H2 in-memory and Postgres databases for deploying the application in different scenarios e.g. CI server. Now we need to deploy it also in MySQL and by default wrapping identifiers in double-quotes is not supported. However, following directions from this post mysql double-quoted table names I see we can set this session parameter and then it should work.
How can I set this session parameter while opening the connection through the MySQL Java Connector? My database URL looks like this: jdbc:mysql://odysseus:3306/idxsrs-trading?param=xxx

Mysql session variable in JDBC string
Using the above to link in combination with the link you've posted, I'd try this.
jdbc:mysql://localhost:3306/db?sessionVariables=sql_mode=ANSI_QUOTES

Related

Java common JDBC SQL Query strategy for Unit Test using HSQLDB and runtime using MySQL

I am developing Java Vert.x 3 application. I use HSQLDB for testing with in-memory DB and MySQL 8.0.20 for runtime. When the vertx verticle is deployed, it initializes the db and tables. Since this is a common code and there are differing SQL syntax between HSQLDB and MySQL and more ridiculously, the HSQLDB capitalizes all the property names and I have to double-quote the properties to use lower-case. I wonder how to achieve this. Here are my questions:
(1) HSQLDB uses "IDENTITY" keyword for creating the in-memory database table. This results in runtime error in MySQL DB as "IDENTITY" is not valid keyword. This poses a challenge that I am facing now.
(2) If it is not possible to have a common SQL syntax which satisfies both MySQL and HSQLDB, what's the best approach to split this common execution path based on the java application runtime profile since this DB initialization is done in the start function of the verticle which is the core of the application?
Any advice and insight is appreciated.
You can create the HSQLDB database with MySQL compatibility mode (append ;sql.syntax_mys=true to the JDBC URL. In this mode, you can do the following:
Use MySQL syntax for CREATE TABLE. HSQLDB understands MySQL's AUTO_INCREMENT keyword as an alias for IDENTITY. It also understands all other MySQL-specific syntax.
The capitalization of column names is really not a problem. With the column names capitalized, you can use any case without quoting in your SELECT statements. This means you can run the same query that you use for MySQL on HSQLDB.
See http://hsqldb.org/doc/2.0/guide/compatibility-chapt.html#coc_compatibility_mysql
Solution: Ditch HSQLDB and use H2 with database_to_upper=false option.

How to add schema/other user to database url given to java?

I'm trying to connect a spring boot java application to an Oracle database. Oracle SQL Developer shows the tables I wish to query being in the DB named testdb under Other users -> `testUser.
I can connect to the DB using url jdbc:oracle:thin:#localhost:1521:testdb. However, when I use an SQL statement
SELECT * FROM SCHEMA_DEFINITION WHERE SCHEMA_NM = ?
Java doesn't find the table named SCHEMA_DEFINITION. Using testUser.SCHEMA_DEFINITION in the SQL statement does work. How can I tell Java to look for all the tables in Other users->testUser?
I have tried setting the datasource's schema (dataSource.setSchema("testUser");) and changing the url (adding ?search_path=testUser and ?currentSchema=testUser).
None of these work.
it's not a java issue, what you need is to log into the user testUser so you can query those tables without the verbose syntax if you really need to keep these queries as is, and run them from testdb then you need to create synonyms for those tables inside testdb schema:
CREATE SYNONYM TESTDB.SCHEMA_DEFINITION FOR testUser.SCHEMA_DEFINITION;
do this for each table and they will work.
Found the solution in github.com/embulk/embulk-input-jdbc/issues/144. dataSource.setSchema("testUser"); works if I use ojdbc7 (I was using ojdbc6 in my pom.xml).

Hibernate + JPA + jTDS + SQL Server = Unicode Problems

I maintain a piece of software that runs as a Servlet and can make use of MySQL, Oracle or SQL Server as the DB backend - depending on what the Customer wants to use.
Everything works perfectly with MySQL and Oracle, and SQL Server works great too, except I cannot insert/update Unicode sequences into the database.
I can do a manual insert in SQL Server Management Studio of a unicode sequence like this
INSERT INTO mytable (msg) VALUES (N'Modern Standard Hindi (मानक हिन्दी), is a standardised and Sanskritised register of the Hindustani language.')
This data is output in my software correctly, so this verifies that the database and the web front end can both handle unicode no problem.
And here's my connection string
jdbc:jtds:sqlserver://<server ip>:1433/MyDb
As I said, Oracle and MySQL work perfectly using this setup. What's different about SQL Server?
Note: I also tried the official Microsoft-provided JDBC driver with exactly the same results.
If it makes a difference, I'm using JPA Repositories to do my DB interactions. The whole webapp is also set up as a SpringMVC application.
Edit: I also tried adding useUnicode=true;characterEncoding=UTF-8 to the end of my connection string with the same results
You may need to specify in your connection string that you're using Unicode, and also what encoding you're using. Maybe something like this?
jdbc:jtds:sqlserver://<server_ip>:1433;databaseName=MyDb;useUnicode=true;characterEncoding=UTF-8
So there was one thing I left off my original question.
I had the system set up with Spring Security and a CharacterEncodingFilter in the filter chain to force UTF-8 in all requests and responses, but I had it set up in the afterSpringSecurityChain section of my web security initializer.
I moved the filter into the beforeSpringSecurityChain method and boom - everything UTF-8 works perfectly with all DB vendors.
I ended up not adding any params to my connection string or anything either. It was literally just the filter that I changed.

How to see all tables in my h2 database at localhost:8082?

I use JDBC and created h2 database called usaDB from sql script. Then I filled all tables with jdbc.
The problem is that after I connect to usaDB at localhost:8082 I cannot see on the left tree
my tables. There is only INFORMATION_SCHEMA database and rootUser which I specified creating usaDB.
How to view the content of tables in my h2 database?
I tried query SELECT * FROM INFORMATION_SCHEMA.TABLES.
But it returned many table names except those I created. My snapshot:
I had the same issue and the answer seems to be really stupid: when you type your database name you shouldn't add ".h2.db" suffix, for example, if you have db file "D:\somebase.h2.db" your connection string should be like "jdbc:h2:file:/D:/somebase". In other way jdbc creates new empty database file named "somebase.h2.db.h2.db" and you see what you see: only system tables.
You can use the SHOW command:
Using this command, you can lists the schemas, tables, or the columns of a table. e.g.:
SHOW TABLES
This problem drove me around the twist and besides this page I read many (many!) others until I solved it.
My Use Case was to see how a SpringBatch project created in STS using :: Spring Boot :: (v1.3.1.RELEASE) was going to behave with the H2 database; to do the latter, I needed to be able to get the H2 console running as well to query the DB results of the batch run.
This is what I did and found out:
Created an Web project in STS using Spring Boot:
Added the following to the pom.xml of the latter:
Added a Spring configuration file as follows to the project:
This solves the Web project deficiencies in STS. If you run the project now, you can access the H2 console as follows: http://localhost:8080/console
Now create a SpringBatch project in STS as follows (the alternative method creates a different template missing most of the classes for persisting data. This method creates 2 projects: one Complete, and the other an initial. Use the Complete in the following.):
The SpringBatch project created with STS uses an in memory H2 database that it CLOSES once the application run ends; once you run it, you can see this in the logging output.
So what we need is to create a new DataSource that overrides the default that ships with the project (if you are interested, just have a look at the log messages and you will see that it uses a default datasource...this is created from:
o.s.j.d.e.EmbeddedDatabaseFactory with the following parameters:
Starting embedded database: url='jdbc:hsqldb:mem:testdb', username='sa')
So, it starts an in memory, and then closes it. You have no chance of seeing the data with the H2 console; it has come and gone.
So, create a DataSource as follows:
You can of course use a properties file to map the parameters, and profiles for different DataSource instances...but I digress.
Now, make sure you set the bit that the red arrow in the picture is pointing to, to a location on your computer where a file can be persisted.
Running the SpringBatch (Complete project) you should now have a db file in that location after it runs (persisting Person data)
Run the Web project you configured previously in these steps, and you WILL :=) see your data, and all the Batch job and step run data (et voila!):
Painful but rewarding. Hope it helps you to really BOOTSTRAP :=)
I have met exactly this problem.
From what you describe, I suppose that you connect your jdbc with the "real" h2 server, but you are connecting on web application to database by the wrong mode (embedded-in-memory mode, aka h2mem). It means that h2 will create a new database in-memory, instead of using your true database stored elsewhere.
Please make sure that when you connect to this database, you use the mode Generic H2 (Server), NOTGeneric H2 (Embedded). You can refer to the picture below.
Version of jar file and installed h2 database should be same.
If in case you have created and populated H2 database table using maven dependency in spring boot, then please do change the JDBC URL as jdbc:h2:mem:testdb while connecting to H2 using web console.
It is an old question, but I came across the same problem. Eventually I found out that the default JDBC URL is pointing a test server rather than my application. After correcting it, I could access the right DB.
I tried with both Generic H2 (Embedded) and the Generic H2 (Server) options, both worked as long as the JDBC URL: is provided correctly.
In grails 4.0.1 the jdbc URL for development is jdbc:h2:mem:devDb. Check your application.yml file for the exact URL.
For the people who are using H2 in embedded(persistent mode) and want to "connect" to it from IntelliJ(other IDEs probably apply too).
Using for example jdbc url as follows: jdbc:h2:./database.h2
Note, that H2 does not allow implicit relative paths, and requires adding explicit ./
Relative paths are relative to current workdir
When you run your application, your workdir is most likely set to your project's root dir
On the other hand, IDE's workdir is most likely not your project's root
Hence, in IDE when "connecting" to your database you need to use absolute path like: jdbc:h2:/Users/me/projects/MyAwesomeProject/database.h2
For some reason IntelliJ by default also adds ;MV_STORE=false. It disables MVStore engine which in fact is currently used by default in H2.
So make sure that both your application and your IDE use the same store engine, as MVStore and PageStore have different file layouts.
Note that you cannot "connect" to your database if your application is using it because of locking. The other way around applies too.
In my case the issue was caused by the fact that I didn't set the h2 username, password in java. Unfortunatelly, Spring didn't display any errors to me, so it was not easy to figure out. Adding this lines to dataSource method helped me fix the issue:
dataSource.setUsername("sa");
dataSource.setPassword("");
Also, I should have specified the schema when creating tables in schema.sql
Selecting Generic H2 (Server) solved for me. We tempted to use default Generic H2 (Embedded) which is wrong.

How to set default schema in a Spring/mybatis application with Oracle DB?

Coming from a mysql background, I am able to set the default schema name that I want to use for all my sql queries in the connection url. I now have an Oracle DB that I need to access. I am aware that I cannot specify the schema I want to use in the URL since the user is the schema name being used.
I realize that I can use a line of SQL code:
ALTER SESSION SET CURRENT_SCHEMA=default_schema
The project is using mybatis 2.3.5 as my SQL framework, but I am completely new to mybatis. Is there a simple way to configure mybatis to accomplish this? My application is a Spring 3 application, so I am using the Spring DataSourceTransactionManager to manage my transactions. I would presume that the manager must be made aware of this requirement to ensure that the command is sent whenever creating a new connection.
I've tried searching online, but most of the examples I find all have the schema names included within the sql queries in the SqlMaps, which I find to be bad practice.
In an ideal world, the schema name would be part of the URL such that I can make changes to the schema name for different environments (ex: dev, test, prod, etc) without touching the code (ie: only configured at the JNDI/application server level). I would be happy if I could use a Spring configuration value to set this as well as I could still use a JNDI lookup or a system environment property to retrieve the value.
Can anyone point me in the right direction?
Thanks,
Eric
As far as I know, there is no option in Oracle to change your URL in order to connect to a specific user schema.
1) mybatis: You may set your current schema to a deserved one before you start your operations. You can write your specification in a property file and set your method's arguments from that file. You do not need to change your code to change your schema in that case.
<update id="mySetSchemaMethod" parameterClass="String">
ALTER SESSION SET CURRENT_SCHEMA = ${schemaName}
</update>
2) trigger: If you are using this connection only for this particular java application, you can set a client event trigger so set your CURRENT_SCHEMA. This time, you need to change the trigger in order to manage test/prod changes.
CREATE OR REPLACE TRIGGER Set_Schema_On_Logon
AFTER LOGON
ON MY_SCHEMA
BEGIN
ALTER SESSION SET CURRENT_SCHEMA = MY_TEST_SCHEMA;
END;

Categories