separate persistence context for PostgreSQL's schema [duplicate] - java

Is it possible? Can i specify it on the connection URL? How to do that?

I know this was answered already, but I just ran into the same issue trying to specify the schema to use for the liquibase command line.
Update
As of JDBC v9.4 you can specify the url with the new currentSchema parameter like so:
jdbc:postgresql://localhost:5432/mydatabase?currentSchema=myschema
Appears based on an earlier patch:
http://web.archive.org/web/20141025044151/http://postgresql.1045698.n5.nabble.com/Patch-to-allow-setting-schema-search-path-in-the-connectionURL-td2174512.html
Which proposed url's like so:
jdbc:postgresql://localhost:5432/mydatabase?searchpath=myschema

As of version 9.4, you can use the currentSchema parameter in your connection string.
For example:
jdbc:postgresql://localhost:5432/mydatabase?currentSchema=myschema

If it is possible in your environment, you could also set the user's default schema to your desired schema:
ALTER USER user_name SET search_path to 'schema'

I don't believe there is a way to specify the schema in the connection string. It appears you have to execute
set search_path to 'schema'
after the connection is made to specify the schema.

DataSource – setCurrentSchema
When instantiating a DataSource implementation, look for a method to set the current/default schema.
For example, on the PGSimpleDataSource class call setCurrentSchema.
org.postgresql.ds.PGSimpleDataSource dataSource = new org.postgresql.ds.PGSimpleDataSource ( );
dataSource.setServerName ( "localhost" );
dataSource.setDatabaseName ( "your_db_here_" );
dataSource.setPortNumber ( 5432 );
dataSource.setUser ( "postgres" );
dataSource.setPassword ( "your_password_here" );
dataSource.setCurrentSchema ( "your_schema_name_here_" ); // <----------
If you leave the schema unspecified, Postgres defaults to a schema named public within the database. See the manual, section 5.9.2 The Public Schema. To quote hat manual:
In the previous sections we created tables without specifying any schema names. By default such tables (and other objects) are automatically put into a schema named “public”. Every new database contains such a schema.

I submitted an updated version of a patch to the PostgreSQL JDBC driver to enable this a few years back. You'll have to build the PostreSQL JDBC driver from source (after adding in the patch) to use it:
http://archives.postgresql.org/pgsql-jdbc/2008-07/msg00012.php
http://jdbc.postgresql.org/

In Go with "sql.DB" (note the search_path with underscore):
postgres://user:password#host/dbname?sslmode=disable&search_path=schema

Don't forget SET SCHEMA 'myschema' which you could use in a separate Statement
SET SCHEMA 'value' is an alias for SET search_path TO value. Only one
schema can be specified using this syntax.
And since 9.4 and possibly earlier versions on the JDBC driver, there is support for the setSchema(String schemaName) method.

Related

Flyway Found non-empty schema on empty schema

I am trying to implement DB migration with Flyway 4.2.0 + Oracle 11g
I have this empty schema:
And when I try to migrate, Flyway says:
Caused by: org.flywaydb.core.api.FlywayException: Found non-empty
schema(s) "PASHA" without metadata table! Use baseline() or set
baselineOnMigrate to true to initialize the metadata table.
This is the config:
#Bean(initMethod = "migrate")
Flyway flyway() {
Flyway flyway = new Flyway();
flyway.setBaselineOnMigrate(false);
flyway.setSchemas("PASHA");
flyway.setLocations("classpath:db/migration/oracle");
flyway.setDataSource("jdbc:oracle:thin:#host:1521:test", "login", "password");
return flyway;
}
Why do I get this message? My base is empty.
Flyway itself uses a query to check if the schema is empty.
In the case of oracle, the query is:
SELECT * FROM ALL_OBJECTS WHERE OWNER = ?
Execute that query (with your owner in the place of ?) and see if it returns something (it does).
For instance, LOBs that haven't been purged show there. If that's the case, try:
purge recyclebin;
and the query should be empty now.
You need to either let Flyway create the schema itself (meaning there should not be a 'PASHA' schema created before hand), or baseline the existing schema (meaning setting your configuration with flyway.setBaselineOnMigrate(true) ).
Basically, Flyway tries to create a schema ('PASHA' in your example) which already exists.
Adding all of these helped. But the one without spring actually did the trick! Silly as it is, but just worked!
spring.flyway.baselineOnMigrate=true
spring.flyway.baseline-on-migrate = true
flyway.baseline-on-migrate= true
flyway.baselineOnMigrate=true

HsqlException: type not found or user lacks privilege: NUMBER

I'm using hsql 2.3.3. According to documentation I can fix this either by adding additional statement to the sql
SET DATABASE SQL SYNTAX ORA TRUE
or by adding property to the url
url: jdbc:h2:mem:test;sql.syntax_ora=true
First one fixes the issue for me (so this is root cause of it), but I would like to use second one as it looks more generalized for me. But url property does't do the trick. What I'm missing?
The URL property works only if you create a new database with the connection property. The new database will then include the SQL statement and run it automatically at each startup.

How to get Column Comments in JDBC

I want to fetch Column comments using JDBC Metadata , But everytime it returns null , I tested with Oracle and SqlServer both cases it returning Null.
DatabaseMetaData dmt = con.getMetaData();
colRs = dmt.getColumns(null, "dbo", 'Student', null);
while (colRs.next()) {
System.out.println(colRs.getString("REMARKS");
}
While i am getting all other data like column name , length etc absolutely ok ...
For Oracle you need to provide a connection property remarksReporting and set that to true or call the method setRemarksReporting() to enable that.
OracleConnection oraCon = (OracleConnection)con;
oraCon.setRemarksReporting(true);
After that, getColumns() will return the column (or table) comments in the REMARKS column of the ResultSet.
See Oracle's JDBC Reference for more details
For SQL Server this is not possible at all.
Neither the Microsoft nor the jTDS driver expose table or column comments. Probably because there is no SQL support for that in SQL Server. The usual approach of using "extended properties" and the property name MS_DESCRIPTION is not reliable. Mainly because there is no requirement to us MS_DESCRIPTION as the property name. Not even sp_help returns those remarks. And at least the jTDS driver simply calls sp_help go the the table columns. I don't know what the Microsoft driver does.
The only option you have there, is to use fn_listextendedproperty() to retrieve the comments:
e.g.:
SELECT objname, cast(value as varchar(8000)) as value
FROM fn_listextendedproperty ('MS_DESCRIPTION','schema', 'dbo', 'table', 'Student', 'column', null)
You need to replace MS_DESCRIPTION with whatever property name you use to store your comments.

Querying the appropriate database schema

This is a follow-on question to my earlier question about specifying multiple schemata in java using jooq to interact with H2.
My test H2 DB currently has 2 schemata, PUBLIC and INFORMATION_SCHEMA. PUBLIC is specified as the default schema by H2. When running a query that should extract information from eg INFORMATION_SCHEMA.TABLES the query fails with a "table unknown" SQL error. I am only able to execute such queries by executing a factory.use(INFORMATION_SCHEMA). There are no build errors etc and eclipse properly autocompletes eg TABLES.TABLE_NAME.
If I dont do this, jooq doesnt seem to prepend the appropriate schema even though I create the correct Factory object for the schema eg
InformationSchemaFactory info = new InformationSchemaFactory(conn);
I read about mapping but am a bit confused as to which schema I would use as the input/output.
By default, the InformationSchemaFactory assumes that the supplied connection is actually connected to the INFORMATION_SCHEMA. That's why schema names are not rendered in SQL. Example:
// This query...
new InformationSchemaFactory(conn).selectFrom(INFORMATION_SCHEMA.TABLES).fetch();
// ... renders this SQL (with the asterisk expanded):
SELECT * FROM "TABLES";
The above behaviour should be documented in your generated InformationSchemaFactory Javadoc. In order to prepend "TABLES" with "INFORMATION_SCHEMA", you have several options.
Use a regular factory instead, which is not tied to any schema:
// This query...
new Factory(H2, conn).selectFrom(INFORMATION_SCHEMA.TABLES).fetch();
// ... renders this SQL:
SELECT * FROM "INFORMATION_SCHEMA"."TABLES";
Use another schema's factory, such as the generated PublicFactory:
// This query...
new PublicFactory(conn).selectFrom(INFORMATION_SCHEMA.TABLES).fetch();
// ... renders this SQL:
SELECT * FROM "INFORMATION_SCHEMA"."TABLES";
Use Settings and an appropriate schema mapping to force the schema name to be rendered.
The first option is probably the easiest one.
This blog post here will give you some insight about how to log executed queries to your preferred logger output: http://blog.jooq.org/2011/10/20/debug-logging-sql-with-jooq/

Retrieve column Default with Derby DB via JDBC

I have a table with a column defined like this:
Country VARCHAR(2) NOT NULL DEFAULT 'US'
When I try to detect this default with JDBC it fails. Basically when I use DatabaseMetaData.getColumns the result does not contain the COLUMN_DEFAULT column. It is there when I try this with H2.
Any ideas how to get the default with Derby?
Did you try for COLUMN_DEFAULT? Or for COLUMN_DEF? According to the Javadoc I think it should be COLUMN_DEF.
Also, what version of Java and of JDBC are you using? I think that Derby only added COLUMN_DEF as part of the JDBC 4.0 support, which may require Java 1.6.

Categories