jOOQ has CREATE TABLE syntax as stated in the documentation:
create.createTable(AUTHOR)
.column(AUTHOR.ID, SQLDataType.INTEGER)
.column(AUTHOR.FIRST_NAME, SQLDataType.VARCHAR.length(50))
.column(AUTHOR_LAST_NAME, SQLDataType.VARCHAR.length(50))
.execute();
I'm wondering how to define which column belongs to the primary key? So is there a way in jOOQ to create a CREATE TABLE statement with PRIMARY KEY information?
I'm specifically interested in a solution for SQLite, which doesn't have syntax to add the primary key afterwards, so I think in worst case I have to go to a DB specific solution?
This feature has been implemented for jOOQ 3.8: #4050.
create.createTable(AUTHOR)
.column(AUTHOR.ID, SQLDataType.INTEGER)
.column(AUTHOR.FIRST_NAME, SQLDataType.VARCHAR.length(50))
.column(AUTHOR_LAST_NAME, SQLDataType.VARCHAR.length(50))
.constraints(
constraint("PK_AUTHOR").primaryKey(AUTHOR.ID)
)
.execute();
Since jOOQ 3.6 (#3338), you can also use the ALTER TABLE statement to add a constraint after creating the table:
create.alterTable(AUTHOR)
.add(constraint("PK_AUTHOR").primaryKey(AUTHOR.ID))
.execute();
Related
i have a question, i duplicated a table with:
Table<?> table = DSL.table(DSL.name("dc2", "process"));
dsl.createTable(table).as(dsl.select().from("dc1.process")).withNoData().execute();
but doesn't copy a primary key and foreignkey, how i do?
and if i want to duplicate schema in jooq?
thanks
Giuseppe
If you're using the code generator to produce your original schema, you can duplicate it relatively easily using:
Runtime schema mapping: https://www.jooq.org/doc/latest/manual/code-generation/codegen-advanced/codegen-config-database/codegen-database-catalog-and-schema-mapping/
DSLContext.ddl() and/or Meta.ddl()
A more convenient syntax will be supported in the future via standard SQL CREATE TABLE (.. LIKE othertable) syntax:
https://github.com/jOOQ/jOOQ/issues/8860
Or a synthetic CREATE SCHEMA .. LIKE otherschema syntax:
https://github.com/jOOQ/jOOQ/issues/9527
I'm trying to imagine how to use jOOQ with bridge tables.
Suppose you have
CREATE TABLE TableA (
id BIGSERIAL PRIMARY KEY
)
CREATE TABLE TableB (
id BIGSERIAL PRIMARY KEY
)
CREATE TABLE TableBridge (
id BIGSERIAL,
table_a_id INTEGER NOT NULL,
table_b_id INTEGER NOT NULL,
CONSTRAINT tablea_pk_id PRIMARY KEY (table_a_id)
REFERENCES TableA (id) MATCH SIMPLE,
CONSTRAINT tableb_pk_id PRIMARY KEY (table_b_id)
REFERENCES TableB (id) MATCH SIMPLE
)
When mapping this schema using jOOQ there will be three record classes, TableARecord, TableBRecord and TableBridgeRecord.
If I want to persist through an insert a record for TableA, should I simply first create and persist the TableB records, then persit rows for TableB and then manually add the TableBridge rows? Isn't there any way to automatically save also the rows in the bridge table?
There are several ways to solve this kind of problem:
1. Do it with a "single" jOOQ statement (running three SQL statements)
The most idiomatic way to solve this kind of problem with standard jOOQ would be to write a single SQL statement that takes care of all three insertions in one go:
ctx.insertInto(TABLE_BRIDGE)
.columns(TABLE_BRIDGE.TABLE_A_ID, TABLE_BRIDGE.TABLE_B_ID)
.values(
ctx.insertInto(TABLE_A)
.columns(TABLE_A.VAL)
.values(aVal)
.returning(TABLE_A.ID)
.fetchOne()
.get(TABLE_A.ID),
ctx.insertInto(TABLE_B)
.columns(TABLE_B.VAL)
.values(bVal)
.returning(TABLE_B.ID)
.fetchOne()
.get(TABLE_B.ID)
)
.execute();
The above works with jOOQ 3.8. Quite possibly, future versions will remove some of the verbosity around returning() .. fetchOne() .. get().
2. Do it with a single SQL statement
I assume you're using PostgreSQL from your BIGSERIAL data type usage, so the following SQL statement might be an option to you as well:
WITH
new_a(id) AS (INSERT INTO table_a (val) VALUES (:aVal) RETURNING id),
new_b(id) AS (INSERT INTO table_b (val) VALUES (:bVal) RETURNING id)
INSERT INTO table_bridge (table_a_id, table_b_id)
SELECT new_a.id, new_b.id
FROM new_a, new_b
The above query is currently not supported entirely via jOOQ 3.8 API, but you can work around the jOOQ API's limitations by using some plain SQL:
ctx.execute(
"WITH "
+ " new_a(id) AS ({0}), "
+ " new_b(id) AS ({1}) "
+ "{2}",
// {0}
insertInto(TABLE_A)
.columns(TABLE_A.VAL)
.values(aVal)
.returning(TABLE_A.ID),
// {1}
insertInto(TABLE_B)
.columns(TABLE_B.VAL)
.values(bVal)
.returning(TABLE_B.ID),
// {2}
insertInto(TABLE_BRIDGE)
.columns(TABLE_BRIDGE.TABLE_A_ID, TABLE_BRIDGE.TABLE_B_ID)
.select(
select(field("new_a.id", Long.class), field("new_b.id", Long.class))
.from("new_a, new_b")
)
);
Clearly also here, there will be improvements in future jOOQ APIs.
3. Do it with UpdatableRecords
In this particular simple case, you could get away simply by calling:
TableARecord a = ctx.newRecord(TABLE_A);
a.setVal(aVal);
a.store();
TableBRecord b = ctx.newRecord(TABLE_B);
b.setVal(bVal);
b.store();
TableBridgeRecord bridge = ctx.newRecord(TABLE_BRIDGE);
bridge.setTableAId(a.getId());
bridge.setTableBId(b.getId());
bridge.store();
I am trying to create a Vertica table with JOOQ 3.5.x:
Connection connection = create();
DSLContext dslContext = DSL.using(connection);
Field<String> myColumn = DSL.field("my_column", SQLDataType.VARCHAR);
Table table = DSL.tableByName("my_schema", "my_table");
dslContext.createTable(table)
.column(myColumn, myColumn.getDataType())
.execute();
This fails on Schema "my_schema" does not exist.
I can solve it with:
dslContext.execute("create schema if not exists my_schema");
But is there a more elegant way to create a schema with JOOQ?
Currently JOOQ covers just a subset of the possible DDL statements that can be executed against a server and schema management is not yet included so you have to drop back to plan old SQL.
If you need to do a lot of DDL work you should start to look at the latest version 3.8 as this has extend the capabilities to include
DEFAULT column values in CREATE TABLE or ALTER TABLE statements
IF EXISTS in DROP statements
IF NOT EXISTS in CREATE statements
ALTER TABLE .. { RENAME | RENAME COLUMN | RENAME CONSTRAINT } statements
Version 3.6 added
ALTER TABLE ADD CONSTRAINT (with UNIQUE, PRIMARY KEY, FOREIGN KEY, CHECK)
ALTER TABLE DROP CONSTRAINT
CREATE TEMPORARY TABLE
have created my tables and relationships in the database PostgreSQL, but when I want to generate Hibernate Mapping Files and POJOs, they are not generated
I applied all the appropriate steps to hibernate.cfg.xml generation and hibernate.reveng.xml
I think it's because the name tables and fields that I have in all uppercase, because I tested with another BD with the names of the tables in lower case and if it works normally, I show the script of my tables.
CREATE TABLE "public"."T_LNEA"(
"ID_LNEA" Integer NOT NULL,
"ID_CTGRIA" Integer NOT NULL,
"DSCRPCION" Character varying(200)
)
WITH (OIDS=FALSE)
;
ALTER TABLE "public"."T_LNEA" ADD CONSTRAINT "PK_ID_LNEA" PRIMARY KEY ("ID_LNEA")
;
CREATE TABLE "public"."T_SUB_LNEA"(
"ID_SUB_LNEA" Integer NOT NULL,
"ID_LNEA" Integer NOT NULL,
"DSCRPCION" Character varying(200)
)
WITH (OIDS=FALSE)
;
-- Add keys for table public.T_SUB_LNEA
ALTER TABLE "public"."T_SUB_LNEA" ADD CONSTRAINT "PK_ID_SUB_LNEA" PRIMARY KEY ("ID_SUB_LNEA")
;
CREATE TABLE "public"."T_CTGRIA"(
"ID_CTGRIA" Integer NOT NULL,
"DSCRPCION" Character varying(200)
)
WITH (OIDS=FALSE)
;
ALTER TABLE "public"."T_CTGRIA" ADD CONSTRAINT "PK_ID_CRITERIA" PRIMARY KEY ("ID_CTGRIA")
;
And an image that is loading the tables using the JBOS Tools.
But still I need support because I can not generate the POJOs.
In the File "hibernate.reveng.xml" has the following
<schema-selection match-catalog="mybd" match-schema="mybd"/>
You have to delete the match-schema="mybd".
By default, when you use postgresql in hibernate, appears the match- schema , which does not happen in mysql , delete it and work , checked in Netbeans8.0
Hi, as said before, if I change the name of the table and its fields in lowercase, if generates POJOs, the question is why is not generated in capital letters .....
Une the reverse engineering tools provided by Hibernate. It depends on your IDE.
For example with NetBeans this is how it is done: https://netbeans.org/kb/docs/web/hibernate-webapp.html
You solve it somehow does not recognize the table name in uppercase, but if you recognize the attributes of the table in uppercase, so rename the tables in lowercase temporarily after he change in the EJB annotations, at least it works somehow.
I want to create an Entity class with database in Netbeans.
When I select a Data source jdbc/Ionbank (custom Jdbc connection Using JDBC-ODBC bridge with Ms SQL 2005 as database).
I see all the tables from that database.
All tables show no primary key, but they have primary keys in them.
Things I have tried :-
Created new 4-5 data source.
Created tables using query, and not the New table option.
Tried changing Odbc connection.
Tried using different drivers for the Jdbc-Odbc bridge like Sql4jdbc.jar, Jdts.jar.
I had same issue, but i solved it using the following: "New Entity Classes from Database" cannot process some tables, saying "no primary key"
A quote from that link helped me:
The problem will happen if you have foreign keys where upper case and lower case table names don't match the referenced table's definition.
For instance:
create table OkTable (
id int not null auto_increment
, primary key (id)
);
create table MisunderstoodTable(
id int not null auto_increment
oktable int not null
, primary key (id)
, foreign key ok (oktable) references oktable (id)
);
The MisunderstoodTable has a foreign key where the target table name doesn't match the lower/uppercase name of the referenced table.
To avoid this problem, just make sure you type your foreign key definitions while matching upper/lower casing for the targeted table.