I am trying to save changes via WFS-T using GeoServer:
This is my code that is getting feature from geoserver
var sourceWFS = new ol.source.Vector({
loader: function (extent) {
$.ajax('http://127.0.0.1:8080/geoserver/kairosDB/ows', {
type: 'GET',
data: {
service: 'WFS',
version: '1.1.0',
request: 'getFeature',
typename: 'wfs_geom',
srsname: 'EPSG:3857',
bbox: extent.join(',') + ',EPSG:3857'
}
}).done(function (response) {
sourceWFS.addFeatures(formatWFS.readFeatures(response));
});
},
// strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ()),
strategy: ol.loadingstrategy.bbox,
projection: 'EPSG:3857'
});
And This is code that is saving feature to server
var formatGML = new ol.format.GML({
featureNS: 'http://127.0.0.1:8080/geoserver/kairosDB',
featureType: 'wfs_geom',
srsName: 'EPSG:3857'
});
But When I saveFeature to server, This error's occured
2017-02-01 14:30:02,339 ERROR [geoserver.ows] -
org.geoserver.wfs.WFSTransactionException: {http://127.0.0.1:8080/geoserver/kairosDB}wfs_geom is read-only
at org.geoserver.wfs.Transaction.execute(Transaction.java:269)
at org.geoserver.wfs.Transaction.transaction(Transaction.java:106)
at org.geoserver.wfs.DefaultWebFeatureService.transaction(DefaultWebFeatureService.java:172)
at sun.reflect.GeneratedMethodAccessor195.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
wfs_geom table already has a primary key, create script:
CREATE TABLE public.wfs_geom
(
id bigint NOT NULL,
geometry geometry,
CONSTRAINT wfs_geom_pkey PRIMARY KEY (id)
)
WITH (
OIDS = FALSE
)
TABLESPACE pg_default;
ALTER TABLE public.wfs_geom
OWNER to postgres;
GRANT ALL ON TABLE public.wfs_geom TO postgres;
-- Index: sidx_wfs_geom
-- DROP INDEX public.sidx_wfs_geom;
CREATE INDEX sidx_wfs_geom
ON public.wfs_geom USING gist
(geometry)
TABLESPACE pg_default;
Could you help me?
This works like a charm: http://osgeo-org.1560.x6.nabble.com/Read-only-error-when-editing-a-WFS-T-td5284537.html
There is a rule in the "Data security" section that do allow to write
to this workspace for all, but the writing is not allowed to anonymous
user for all the workspace (..w) The strange behaviour is that in
yesterday I can edit the layer using a client.. and I do not
understand why, moreover using QGIS I cannot edit the layer, but QGIS
support the WFS-T
There are two things you need to change in GeoServer to makes this possible.
Enable Transactional under the WFS tab on GeoServer
Under the Data tab on GeoServer you need to edit the rule ..w to enable the role ROLE_ANONYMOUS
After doing these two things I was able to get rid of this error and post data to GeoServer.
Add a primary key constraint to the table.
Related
I have the following migration file:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateHeadersTable extends Migration
{
public function up()
{
Schema::create('headers', function (Blueprint $table) {
$table->increments('entry')->unsigned();
$table->string('id',16);
$table->string('address',256);
$table->string('desciption',512)->nullable()->default('NULL');
$table->tinyInteger('currency',)->default('0');
$table->decimal('sum',13,4);
$table->datetime('entered');
$table->tinyInteger('aborted',)->default('0');
$table->primary('entry');
});
}
public function down()
{
Schema::dropIfExists('headers');
}
}
This file was automatically generated by an online tool from a SQL file. However, when I ran "php artisan migrate," I got the following error:
SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'headers'
already exists (SQL: create table `headers` (`entry` int unsigned not null
auto_increment primary key, `id` varchar(16) not null, `address`
varchar(256) not null, `desciption` varchar(512) null default 'NULL',
`currency` tinyint not null default '0', `sum` decimal(13, 4) not null,
`entered` datetime not null, `aborted` tinyint not null default '0')
default character set utf8mb4 collate 'utf8mb4_unicode_ci')
at vendor/laravel/framework/src/Illuminate/Database/Connection.php:712
708▕ // If an exception occurs when attempting to run a query, we'll format the error
709▕ // message to include the bindings with SQL, which will make this exception a
710▕ // lot more helpful to the developer instead of just the database's errors.
711▕ catch (Exception $e) {
➜ 712▕ throw new QueryException(
713▕ $query, $this->prepareBindings($bindings), $e
714▕ );
715▕ }
716▕ }
+9 vendor frames
10 database/migrations/2023_01_31_1675138133_create_headers_table.php:23
Illuminate\Support\Facades\Facade::__callStatic()
+22 vendor frames
33 artisan:37
Illuminate\Foundation\Console\Kernel::handle()
I am not familiar with Laravel migration files. How can I fix this? Many thanks!
Do not drop the table manually. use php artisan migrate:rollback
and then re-try php artisan migrate
Error you got states that Table 'headers' already exists in database if you have deleted table from database just check their may be entry in migrations table in database just delete it and run migration again
Trying to follow the Flink CDC Connectors Postgres tutorial using PyFlink:
https://ververica.github.io/flink-cdc-connectors/master/content/quickstart/mysql-postgres-tutorial.html
Failing Code
ddl = """
CREATE TABLE shipments (
shipment_id INT,
order_id INT,
origin STRING,
destination STRING,
is_arrived BOOLEAN
) WITH (
'connector' = 'postgres-cdc',
'hostname' = 'localhost',
'port' = '5432',
'username' = 'postgres',
'password' = 'postgres',
'database-name' = 'postgres',
'schema-name' = 'public',
'slot.name' = 'slot2',
'table-name' = 'shipments'
);
"""
table_env.execute_sql(ddl)
table2: Table = table_env.sql_query("SELECT * FROM shipments")
table2.execute().print()
Main Stacktrace
Caused by: io.debezium.DebeziumException: Creation of replication slot failed
at io.debezium.connector.postgresql.PostgresConnectorTask.start(PostgresConnectorTask.java:141)
at io.debezium.connector.common.BaseSourceTask.start(BaseSourceTask.java:130)
at io.debezium.embedded.EmbeddedEngine.run(EmbeddedEngine.java:759)
at io.debezium.embedded.ConvertingEngineBuilder$2.run(ConvertingEngineBuilder.java:188)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "CREATE_REPLICATION_SLOT"
Position: 1
Troubleshooting
CDC needs access to Postgres' WAL, write ahead log. In order to get the WAL Postgres needs to have a replication slot. So you need to set this up in Postgres, I got that done with this command:
ALTER SYSTEM SET wal_level = logical
SELECT * FROM pg_create_logical_replication_slot('slot2', 'test_decoding')
Then restart Postgres.
CDC code that get the replication slot
jdbcConnection.getReplicationSlotState(connectorConfig.slotName(), connectorConfig.plugin().getPostgresPluginName());
called from:
https://github.com/debezium/debezium/blob/main/debezium-connector-postgres/src/main/java/io/debezium/connector/postgresql/PostgresConnectorTask.java
When that doesn't work you it will try to create the replication slot and that is where the exception is thrown.
Possible version issue
Maybe the problem is that I am running Postgres 13 and Ververica CDC might only support up to Postgres 12.
So
Console:
yarn dev
yarn run v1.22.10
$ nodemon dist/index.js
[nodemon] 2.0.7
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node dist/index.js`
[discovery] ORM entity discovery started, using ReflectMetadataProvider
[discovery] - processing entity Post
[discovery] - entity discovery finished, found 1 entities, took 21 ms
[info] MikroORM successfully connected to database postgres on postgresql://postgres:*****#127.0.0.1:5432
[query] begin
[query] insert into "post" ("created_at", "title", "updated_at") values ('2021-04-05T21:04:23.126Z', 'my first post', '2021-04-05T21:04:23.126Z') returning "_id" [took 12 ms]
[query] rollback
TableNotFoundException: insert into "post" ("created_at", "title", "updated_at") values ('2021-04-05T21:04:23.126Z', 'my first post', '2021-04-05T21:04:23.126Z') returning "_id" - relation "post" does not exist
at PostgreSqlExceptionConverter.convertException (P:\.Projektek\lireddit-server\node_modules\#mikro-orm\postgresql\PostgreSqlExceptionConverter.js:36:24)
at PostgreSqlDriver.convertException (P:\.Projektek\lireddit-server\node_modules\#mikro-orm\core\drivers\DatabaseDriver.js:194:54)
at P:\.Projektek\lireddit-server\node_modules\#mikro-orm\core\drivers\DatabaseDriver.js:198:24
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async PostgreSqlDriver.nativeInsert (P:\.Projektek\lireddit-server\node_modules\#mikro-orm\knex\AbstractSqlDriver.js:150:21)
at async ChangeSetPersister.persistNewEntity (P:\.Projektek\lireddit-server\node_modules\#mikro-orm\core\unit-of-work\ChangeSetPersister.js:55:21)
at async ChangeSetPersister.executeInserts (P:\.Projektek\lireddit-server\node_modules\#mikro-orm\core\unit-of-work\ChangeSetPersister.js:24:13)
at async UnitOfWork.commitCreateChangeSets (P:\.Projektek\lireddit-server\node_modules\#mikro-orm\core\unit-of-work\UnitOfWork.js:496:9)
at async UnitOfWork.persistToDatabase (P:\.Projektek\lireddit-server\node_modules\#mikro-orm\core\unit-of-work\UnitOfWork.js:458:13)
at async PostgreSqlConnection.transactional (P:\.Projektek\lireddit-server\node_modules\#mikro-orm\knex\AbstractSqlConnection.js:53:25)
at async UnitOfWork.commit (P:\.Projektek\lireddit-server\node_modules\#mikro-orm\core\unit-of-work\UnitOfWork.js:183:17)
at async SqlEntityManager.flush (P:\.Projektek\lireddit-server\node_modules\#mikro-orm\core\EntityManager.js:486:9)
at async SqlEntityManager.persistAndFlush (P:\.Projektek\lireddit-server\node_modules\#mikro-orm\core\EntityManager.js:438:9)
previous error: insert into "post" ("created_at", "title", "updated_at") values ('2021-04-05T21:04:23.126Z', 'my
first post', '2021-04-05T21:04:23.126Z') returning "_id" - relation "post" does not exist
at Parser.parseErrorMessage (P:\.Projektek\lireddit-server\node_modules\pg-protocol\dist\parser.js:278:15)
at Parser.handlePacket (P:\.Projektek\lireddit-server\node_modules\pg-protocol\dist\parser.js:126:29)
at Parser.parse (P:\.Projektek\lireddit-server\node_modules\pg-protocol\dist\parser.js:39:38)
at Socket.<anonymous> (P:\.Projektek\lireddit-server\node_modules\pg-protocol\dist\index.js:10:42)
at Socket.emit (events.js:315:20)
at Socket.EventEmitter.emit (domain.js:467:12)
at addChunk (internal/streams/readable.js:309:12)
at readableAddChunk (internal/streams/readable.js:284:9)
at Socket.Readable.push (internal/streams/readable.js:223:10)
at TCP.onStreamRead (internal/stream_base_commons.js:188:23) {
length: 166,
severity: 'ERROR',
code: '42P01',
detail: undefined,
hint: undefined,
position: '13',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'd:\\pginstaller_13.auto\\postgres.windows-x64\\src\\backend\\parser\\parse_relation.c',
line: '1376',
routine: 'parserOpenTable'
}
Index.ts:
import { MikroORM } from "#mikro-orm/core";
import { __prod__ } from "./constants";
import { Post } from "./entities/Post";
import mikroConfig from "./mikro-orm.config";
const main = async () => {
const orm = await MikroORM.init(mikroConfig);
await orm.getMigrator().up;
const post = orm.em.create(Post, { title: "my first post" });
await orm.em.persistAndFlush(post);
};
main().catch((err) => {
console.error(err);
});
Post.ts:
import { Entity, PrimaryKey, Property } from "#mikro-orm/core";
#Entity()
export class Post {
#PrimaryKey()
_id!: number;
#Property({ type: "date" })
createdAt = new Date();
#Property({ type: "date", onUpdate: () => new Date() })
updatedAt = new Date();
#Property({ type: "text" })
title!: string;
}
mikro-orm.config.ts:
import { __prod__ } from "./constants";
import { Post } from "./entities/Post";
import { MikroORM } from "#mikro-orm/core";
import path from "path";
export default {
migrations: {
path: path.join(__dirname, "./migrations"),
pattern: /^[\w-]+\d+\.[tj]s$/,
},
entities: [Post],
dbName: "postgres",
debug: !__prod__,
type: "postgresql",
password: "hellothere",
} as Parameters<typeof MikroORM.init>[0];
And the migration I created with npx mikro-orm migration:create:
import { Migration } from '#mikro-orm/migrations';
export class Migration20210405205411 extends Migration {
async up(): Promise<void> {
this.addSql('create table "post" ("_id" serial primary key, "created_at" timestamptz(0) not null, "updated_at" timestamptz(0) not null, "title" text not null);');
}
}
After that im compiling it to js btw, but I guess the problem will be somewhere at my code or idk plz help me, I can give you more info just plz help, I've been trying to fix this bug for 5 hours :/
Btw Im doin Ben Awad's 14 hour fullstack tutorial if its matter.
The TableNotFoundException happens when you try to add data before initializing the table's schema (or structure).
Passing the --initial as in Mosh's Answer did not work for me, possibly because I am passing a username and password in ./mikro-orm.config.ts.
I used Mikro-ORM's SchemaGenerator to initialize the table as seen here in the official docs.
Add the following lines before adding data to post in your main function in index.ts:
const generator = orm.getSchemaGenerator();
await generator.updateSchema();
The main function in index.ts should now look like this:
const main = async () => {
const orm = await MikroORM.init(mikroConfig);
await orm.getMigrator().up;
const generator = orm.getSchemaGenerator();
await generator.updateSchema();
const post = orm.em.create(Post, { title: "my first post" });
await orm.em.persistAndFlush(post);
};
updateSchema creates a table or updates it based on .entities/Post.ts. This could cause issues when the Post file is updated, I haven't run in to any while following Ben's tutorial. Although, I'd still recommend creating ./create-schema.ts and running it when needed as shown in the official docs.
I have had the same issue. This is what I did:
I deleted the migrations folder as well as the dist folder
I ran npx mikro-orm migration:create --initial
After that, I restarted yarn watch and yarn dev and it worked for me.
Notice the --initial flag. I would recommend to check the official documentation. The migrations table is used to keep track of already executed migrations. When you only run npx mikro-orm migration:create, the table will not be created and therefore MikroORM is unable to check if the migration for the Post entity has already been performed (which includes creating the respective table on the database).
Ben does not use the --initial flag in his tutorial, he might have already ran it prior to the tutorial.
I had a similar problem myself (Also doing Ben Awad's tutorial).
I used Mikro-ORM's schema generator to initialize the table like in Fares47's Answer, but the problem still persisted.
It wasn't until I set my user to have Superuser permissions that it started working.
I am using postgresql for my data base which I downloaded using homebrew. If you have a similar set up here is what I did:
Start up psql in your terminal using psql postgres. If you want, you can view your users and check their permissions by typing \du in the shell. Then, to change the permissions for a user use the command ALTER ROLE <username> WITH SUPERUSER;. Make sure you include a semi-colon or else it will not run the command.
Check this article out for more info on psql commands.
I have the same problem i solved by install the ts-node on project
npm i -D ts-node
and set useTsNode on package.json as true.
The problem is the mikro-orm cli only add ts files paths in configPaths if the property useTsNode is true and ts-node is installed.
orther problem that i have is the regex in pattern property in mikro-orm.config.ts was wrong because a typo.
If any of the suggested steps didnt solve it for you, simply...
quit yarn watch and yarn dev
run this command from the command line
npx mikro-orm migration:up
now restart watch and dev and it you should be good.
from https://mikro-orm.io/docs/migrations/#migration-class
I also experienced this. And like Fares47 said it's possibly because I passed the username and password in ./mikro-orm.config.ts.
And my solution is simply execute the sql command that generated in ./src/migrations/Migration<NUMBERS>.ts file in postgresql terminal.
Here is the command that I execute in the database,
create table "post" ("id" serial primary key, "created_at" timestamptz(0) not null, "updated_at" timestamptz(0) not null, "title" text not null);
Just like what they suggested in the doc,
A safe approach would be generating the SQL on development server and
saving it into SQL Migration files that are executed manually on the
production server.
Little Background Story
Here is my scenario, I have a database named Location in my MariaDB, and I have a User database in my Postgres. I want to chain two of them in my Postgres DB. So I have two tables users and userLocations. Oh yeah, a nice thing to note is that I only have access to read (SELECT and CREATE VIEW) from LocationDB, and connecting to UserDB as root. Yes I have successfully authenticate() both of them. I even able to receive data from LocationDB however the only problem right now is creating that relation between User and Location. Error logs available on the bottom.
Here is my models:
models/user.js
// ... Connection to UserDB (uses Postgres)
const UserDB = require('../datasources/user-db')
const User = UserDB.define('user', {
id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true },
name: { type: Sequelize.STRING, allowNull: false }
})
module.exports = User
models/location.js
// Connection to LocationDB (uses MariaDB)
const LocationDB = require('../datasources/location-db')
const Location = LocationDB.define('ms_location', {
id_Location: { type: Sequelize.INTEGER, primaryKey: true },
name_Location: { type: Sequelize.STRING, allowNull: false }
}, { timestamps: false, freezeTableName: true })
module.exports = Location
models/user-location.js
// ... Connection to UserDB (uses Postgres)
const UserDB = require('../datasources/user-db')
const UserLocation = UserDB.define('userLocation', {
id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }
})
module.exports = UserLocation
app.js
const Location = require('./models/location')
const User = require('./models/user')
const UserLocation = require('./models/user-location')
User.belongsToMany(Location, { through: UserLocation })
This is a minified version of the case, if you need more information please do ask as I am still new to sequelize as well
The error log: (sorry I don't have any idea to beautify it)
{ SequelizeDatabaseError: relation "ms_location" does not exist
at Query.formatError (<path-to-project>/node_modules/.registry.npmjs.org/sequelize/5.8.6/node_modules/sequelize/lib/dialects/postgres/query.js:354:16)
at query.catch.err (<path-to-project>/node_modules/.registry.npmjs.org/sequelize/5.8.6/node_modules/sequelize/lib/dialects/postgres/query.js:71:18)
at tryCatcher (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/promise.js:517:31)
at Promise._settlePromise (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/promise.js:574:18)
at Promise._settlePromise0 (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/promise.js:619:10)
at Promise._settlePromises (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/promise.js:695:18)
at _drainQueueStep (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/async.js:138:12)
at _drainQueue (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/async.js:131:9)
at Async._drainQueues (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/async.js:147:5)
at Immediate.Async.drainQueues [as _onImmediate] (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:705:18)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)
name: 'SequelizeDatabaseError',
parent:
{ error: relation "ms_location" does not exist
at Connection.parseE (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:602:11)
at Connection.parseMessage (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:399:19)
at Socket.<anonymous> (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:121:22)
at Socket.emit (events.js:189:13)
at addChunk (_stream_readable.js:284:12)
at readableAddChunk (_stream_readable.js:265:11)
at Socket.Readable.push (_stream_readable.js:220:10)
at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
name: 'error',
length: 107,
severity: 'ERROR',
code: '42P01',
detail: undefined,
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'namespace.c',
line: '426',
routine: 'RangeVarGetRelidExtended',
sql:
'CREATE TABLE IF NOT EXISTS "userLocations" ("id" SERIAL , "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" INTEGER REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE, "msLocationIdLocation" INTEGER REFERENCES "ms_location" ("id_Location") ON DELETE CASCADE ON UPDATE CASCADE, UNIQUE ("userId", "msLocationIdLocation"), PRIMARY KEY ("id"));' },
original:
{ error: relation "ms_location" does not exist
at Connection.parseE (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:602:11)
at Connection.parseMessage (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:399:19)
at Socket.<anonymous> (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:121:22)
at Socket.emit (events.js:189:13)
at addChunk (_stream_readable.js:284:12)
at readableAddChunk (_stream_readable.js:265:11)
at Socket.Readable.push (_stream_readable.js:220:10)
at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
name: 'error',
length: 107,
severity: 'ERROR',
code: '42P01',
detail: undefined,
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'namespace.c',
line: '426',
routine: 'RangeVarGetRelidExtended',
sql:
'CREATE TABLE IF NOT EXISTS "userLocations" ("id" SERIAL , "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" INTEGER REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE, "msLocationIdLocation" INTEGER REFERENCES "ms_location" ("id_Location") ON DELETE CASCADE ON UPDATE CASCADE, UNIQUE ("userId", "msLocationIdLocation"), PRIMARY KEY ("id"));' },
sql:
'CREATE TABLE IF NOT EXISTS "userLocations" ("id" SERIAL , "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" INTEGER REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE, "msLocationIdLocation" INTEGER REFERENCES "ms_location" ("id_Location") ON DELETE CASCADE ON UPDATE CASCADE, UNIQUE ("userId", "msLocationIdLocation"), PRIMARY KEY ("id"));' }
You've told Sequelize that you have a table called user and a table called msLocation and that the two are related through another table called userLocation. (Or is it userLocations? Your code and error message are inconsistent.)
It looks like Sequelize is trying to create the userLocations table UserDB but it's failing because as part of the table definition, it's trying to create a foreign key reference to ms_location:
"msLocationIdLocation" INTEGER REFERENCES "ms_location" ("id_Location")
ON DELETE CASCADE ON UPDATE CASCADE
which fails because ms_location is not in the UserDB but rather in the other database.
I don't know if Sequelize can actually handle tables spanning multiple databases servers, but I doubt it. Creating a query that spans two tables in the same database is easy, Sequelize can just create a join. It's a totally different story if the tables are on two different servers; now Sequelize would have to run two different queries and do all the join logic in memory. That's a pretty big lift.
Some databases have a way to create a table in one database that replicates or forwards to a table in another database. If PostgreSQL supports that, you could try using that to replicate or shadow the MariaDB table, which would enable Sequelize to see all the tables as being part of UserDB.
I'm trying to use the timer service provided by Glassfish. Thus, I have to create a table named EJB__TIMER__TBL and configure jdbc resource in Glassfish.
I want to store this table on postgreSQL on a schema named glassfish. So my ddl is this one (I replace the BLOB type to BYTEA) :
CREATE SCHEMA glassfish;
CREATE TABLE glassfish.EJB__TIMER__TBL (
CREATIONTIMERAW BIGINT NOT NULL,
BLOB BYTEA,
TIMERID VARCHAR(255) NOT NULL,
CONTAINERID BIGINT NOT NULL,
OWNERID VARCHAR(255) NULL,
STATE INTEGER NOT NULL,
PKHASHCODE INTEGER NOT NULL,
INTERVALDURATION BIGINT NOT NULL,
INITIALEXPIRATIONRAW BIGINT NOT NULL,
LASTEXPIRATIONRAW BIGINT NOT NULL,
SCHEDULE VARCHAR(255) NULL,
APPLICATIONID BIGINT NOT NULL,
CONSTRAINT PK_EJB__TIMER__TBL PRIMARY KEY (TIMERID)
);
DROP ROLE IF EXISTS glassfish;
CREATE ROLE glassfish WITH NOINHERIT LOGIN PASSWORD '...';
REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA glassfish FROM glassfish;
REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA glassfish FROM glassfish;
GRANT USAGE ON SCHEMA glassfish TO glassfish;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA glassfish TO glassfish;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA glassfish TO glassfish;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA glassfish TO glassfish;
ALTER USER glassfish SET search_path to 'glassfish';
I configured a jdbc pool and resource for Glassfish :
asadmin create-jdbc-connection-pool
--datasourceclassname org.postgresql.ds.PGConnectionPoolDataSource
--restype javax.sql.ConnectionPoolDataSource
--property User=glassfish:Password=...:PortNumber=5432:DatabaseName=...:ServerName=localhost jdbc/simPool/glassfish
asadmin create-jdbc-resource --connectionpoolid jdbc/simPool/glassfish jdbc/sim/glassfish
And I properly enter jdbc/sim/glassfish in the jdbc resource to use for timer service in Glassish GUI.
Each time I deploy my app, I receive Exception :
[#|2013-02-18T11:42:42.562+0100|WARNING|glassfish3.1.2|org.eclipse.persistence.session.file
:/E:/softs/serveurs/glassfish3_1122/glassfish/domains/domain1/applications/ejb-timer-service-app/WEB-INF/classes/___EJB__Timer__App|_ThreadID=58;_ThreadName=Thread-2;|Local Exception Stack:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERREUR: la relation « EJB__TIMER__TBL » n'existe pas
Position : 193
Error Code: 0
Call: SELECT "TIMERID", "APPLICATIONID", "BLOB", "CONTAINERID", "CREATIONTIMERAW", "INITIALEXPIRATIONRAW", "INTERVALDURATION", "LASTEXPIRATIONRAW", "OWNERID", "PKHASHCODE", "SCHEDULE", "STATE" FROM "EJB__TIMER__TBL" WHERE (("OWNERID" = ?) AND ("STATE" = ?))
bind => [2 parameters bound]
Query: ReadAllQuery(name="findTimersByOwnerAndState" referenceClass=TimerState sql="SELECT "TIMERID", "APPLICATIONID", "BLOB", "CONTAINERID", "CREATIONTIMERAW", "INITIALEXPIRATIONRAW", "INTERVALDURATION", "LASTEXPIRATIONRAW", "OWNERID", "PKHASHCODE", "SCHEDULE", "STATE" FROM "EJB__TIMER__TBL" WHERE (("OWNERID" = ?) AND ("STATE" = ?))")
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:644)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:535)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1717)
So my table EJB__TIMER__TBL doesn't seem to be accessible by Glassfish.
When I create another project, configure a persistence.xml file with the same credentials as my pooled connexion above and create a simple query SELECT COUNT(*) FROM EJB__TIMER__TBL, I receive 0 so my connexion is well established and the default schema accessed is glassfish as espected.
In ${glassfish_root}\glassfish\lib\install\databases there is some ddls but neither for postgresql...so where am I doing wrong ?
NB: when I test to configure service timer with MySQL jdbc resource, it's work...
Thanks for help
Ok I found the solution of my problem.
I didn't know that SQL can be case sensitive. Glassfish calls SELECT ... FROM "EJB__TIMER__TBL" with double quotes so I have to create a table named "EJB__TIMER__TBL" not "ejb__timer__tbl" or anything else.
The workaround is just to recreate my table with double quotes :
CREATE TABLE glassfish."EJB__TIMER__TBL" (
"CREATIONTIMERAW" BIGINT NOT NULL,
"BLOB" BYTEA,
"TIMERID" VARCHAR(255) NOT NULL,
"CONTAINERID" BIGINT NOT NULL,
"OWNERID" VARCHAR(255) NULL,
"STATE" INTEGER NOT NULL,
"PKHASHCODE" INTEGER NOT NULL,
"INTERVALDURATION" BIGINT NOT NULL,
"INITIALEXPIRATIONRAW" BIGINT NOT NULL,
"LASTEXPIRATIONRAW" BIGINT NOT NULL,
"SCHEDULE" VARCHAR(255) NULL,
"APPLICATIONID" BIGINT NOT NULL,
CONSTRAINT "PK_EJB__TIMER__TBL" PRIMARY KEY ("TIMERID")
);