The jOOQ Release Note History
jOOQ Release notes
- For an interactive overview, see also https://github.com/jOOQ/jOOQ/issues
- For a formatted text version, see https://www.jooq.org/notes
- For a text version, see https://www.jooq.org/inc/RELEASENOTES.txt
- For an API diff, see https://www.jooq.org/api-diff
Version 3.9.6 - September 27, 2017
Features and Improvements
#6589 | Improve DSLContext.batchStore() Javadoc, indicating that it does not execute MERGE / UPSERT semantics |
Bug Fixes
#6424 | Compilation error in generated code when both SchemaVersionProvider and CatalogVersionProvider are applied |
#6480 | Typo in DSLContext.fetchCount() and error in DSLContext.fetchExists() Javadoc |
#6507 | XMLDatabase doesn't work when dialect is not a SQLDialect.family() |
#6514 | ClobBinding and BlobBinding don't correctly inline their bind values |
#6538 | NullPointerException in AbstractRecord.intern0() |
#6558 | Error in Record.compareTo(...) Javadoc |
#6572 | Trigger generated errors are not fetched through jOOQ's plain SQL API |
#6596 | "Invalid column index" on Oracle stored procedure call when return type is converted to boolean and argument type is defaulted |
#6600 | Exception thrown when creating table with SQLDataType.UUID in MySQL |
Version 3.9.5 - July 28, 2017
This is a patch release with some useful fixes for the 3.9 branch
Features and Improvements
#6448 | Improve TableLike.field(Field) Javadoc |
Bug Fixes
#6437 | Do not return ID on Record.update() when updatablePrimaryKeys is set to false |
#6455 | Code generation regression for <dateAsTimestamp> |
Version 3.9.4 - July 17, 2017
This is a patch release with some useful fixes for the 3.9 branch
Bug Fixes
#6305 | Oracle flashback query for aliased table results in invalid sql |
#6318 | ALTER TABLE .. ADD COLUMN ignores column type's DEFAULT clause |
#6337 | DataType.hasLength(), hasPrecision(), hasScale(), and others should depend on Binding's <T> type |
#6338 | Exception thrown when creating table with converted VARCHAR type |
#6340 | Recognise H2 SYSTEM_SEQUENCE in INFORMATION_SCHEMA.COLUMNS.COLUMN_DEFAULT as an Identity column |
#6341 | JPADatabase with GeneratedValue does not account for dialect |
#6369 | Oracle LocalDate bind variables aren't cast to DATE |
#6384 | Derby requires RESTRICT on DROP SCHEMA statement |
#6392 | SQL Server multiple errors are not propagated if an update count precedes them |
#6396 | Definition.getQualifiedName() is wrong when <outputSchemaToDefault/> is set to true |
#6405 | NullPointerException when fetching unnamed nested records in plain SQL with PostgreSQL |
#6407 | NullPointerException when trying to get mvn help on goal generate |
#6409 | SQL Server doesn't generate any code when top-level inputSchema is specified, but not inputCatalog |
#6417 | <types/> cannot match user-defined types (e.g. PostGIS GEOMETRY) |
Version 3.9.3 - May 30, 2017
This is a patch release with some useful fixes for the 3.9 branch
Bug Fixes
#5778 | Bad Inlining of LocalDate, LocalTime, LocalDateTime, OffsetTime, OffsetDateTime bind values |
#5787 | DataType.getSQLType() doesn't return the right value for java.time types |
#6107 | Bad formatting when combining constraints in CREATE TABLE statement |
#6112 | File does not get renamed on Windows when TABLE_A is renamed to TABLEA |
#6113 | NullPointerException when generating code in single-uppercase-named-database setup on MariaDB and MySQL |
#6119 | Several DB2 fixes |
#6142 | Add identity column support to XMLGenerator |
#6153 | NullPointerException in GenerationUtil with Postgres CITEXT extension applied |
#6164 | XMLGenerator doesn't export <is_nullable/> for columns |
#6166 | XMLDatabase doesn't correctly load UNIQUE keys |
#6176 | Unstable alias generation for derived tables |
#6178 | DefaultTransactionProvider should not roll back to savepoint in top transaction |
#6180 | ClassNotFoundException occures when generate codes form JPA entity by maven plugin |
#6184 | IF EXISTS emulation using THROW doesn't work for SQL Server 2008 |
#6190 | JPADatabase doesn't correctly generate tables for multi-schema entities |
#6192 | Compilation error in generated code when column is called RESULT or PRIME |
#6205 | PL/SQL Records not generated depending on the order of procedures in a package |
#6224 | Field.contains(T) doesn't delegate to Field.contains(Field<T>) when using plain SQL |
#6227 | Edit New issue NoSuchFieldError when using commercial dialect with open source edition in Maven code generation |
#6228 | MySQL enum type doesn't generate correct DDL via DSLContext.ddl() |
#6262 | XMLGenerator: UniqueConstraintCatalog set to referenced key instead of catalog |
#6290 | Don't generate type length modifier for PostgreSQL bytea types in DDL |
#6293 | Improve support for SQL Server date time literals |
#6295 | Configuration.dialect() should return SQLDialect.DEFAULT when null |
Version 3.9.2 - April 20, 2017
This is a patch release with some useful fixes for the 3.9 branch
Features and Improvements
#5861 | Add a configuration option for varargs setters |
Bug Fixes
#5813 | InformationSchema export contains wrong column name |
#5821 | Missing @Support annotations for PostgreSQL on InsertOnDuplicateSetStep.set() |
#5842 | Shouldn't DEBUG log OUT parameters on procedures that don't have any |
#5856 | Outdated link to jooq-export.xsd in Result.formatXML() Javadoc |
#5860 | Data loader unable to decode Base64 encoding binary types |
#5864 | Work around Oracle 12c issue with INSERT .. SELECT into tables with IDENTITY column |
#5880 | Schema version check does not work with Scala |
#5882 | NullPointerException when running Maven code generator plugin without <target/> specification |
#5891 | <expressions/> deprecation message is logged several times by the code generator |
#5893 | H2Database orders tables by ID instead of NAME |
#5937 | Ignore strategy/name when strategy/matchers is present, in code generator |
#5948 | Boolean data type rewrites on Oracle procedures conflict with PL/SQL BOOLEAN data type logic |
#5950 | Compilation error in generated code when applying converter to Oracle NUMBER procedure parameter |
#5976 | Support JTDS limit of 2000 bind variables also for SQL Server |
#5978 | java.util.impl.Contains should check both sides of the expression for array types |
#5980 | ArrayIndexOutOfBoundsException when generating DSLContext.ddl() for DefaultSchema |
#6036 | Do not throw UnsupportedOperationException in DefaultResultSet etc |
#6040 | Possible leaking JDBC Arrays in DefaultExecuteContext.ARRAYS |
#6049 | UDTRecordImpl.readSQL(SQLInput) and writeSQL(SQLOutput) optimisations |
#6059 | StackOverflowError when DefaultBinding.pgFromString() encounters unknown type |
#6061 | NullPointerException thrown when calling Oracle Function with BOOLEAN parameter |
Version 3.9.1 - January 20, 2017
This is a patch release with some useful fixes for the 3.9 branch
Features and Improvements
#5802 | Stop distributing third party dependencies through zip distribution |
Bug Fixes
#5743 | jOOQ-checker is not deployed to Maven Central |
#5752 | Log WARN if users combine nested catalog configurations with top-level inputSchema configuration |
#5756 | Parser cannot parse bind variables |
#5766 | Compilation error in generated schema when table-valued function literal clashes with class name |
#5773 | MockResultSet should call Converter to transform MockResult's <U> back to <T> |
#5777 | DefaultBinding cannot parse +HH timezone offset |
#5786 | KeepNamesGeneratorStrategy generates wrong Keys.java |
#5801 | Oracle 12c support for OFFSET .. FETCH causes ORA-00918 regression on queries with ambiguous column names |
Version 3.9.0 - December 23, 2016
This is another very exciting release
Experimental Parser
This is an extremely exciting strategic feature for jOOQ. jOOQ users are used to creating SQL statements by "manually" creating a SQL expression tree through the jOOQ API. But nothing should prevent us from parsing string-based (and vendor- specific!) SQL statements into jOOQ expression trees. In the future this can be used, for instance, to translate (and format) one SQL dialect into another, making jOOQ not only an excellent SQL client API for Java, but a general-purpose SQL API.
The new Parser API is available from DSLContext.parser() and is currently deprecated as "experimental" (and incomplete). We're including it in jOOQ 3.9 for public review, so we're looking forward for any feedback you may have!
Checker framework integration
We've annotated all of our API with the @Support annotation for quite a while. This annotation allows for documenting what SQL clause or function is available in what SQLDialect (and version). If that's not enough for you, do check out our new JSR 308 / Checker Framework integration, which allows jOOQ API consumers to "type check" their API usage for a given SQL dialect. For instance, using MySQL, you can now get compilation errors if you're accidentally using Oracle-specific API.
More info in this blog post here: https://blog.jooq.org/jsr-308-and-the-checker-framework-add-even-more-typesafety-to-jooq-3-9/
Better Oracle 12c and PL/SQL integration
Oracle 12c introduced a variety of new features that we finally support in jOOQ as well, including the new IDENTITY column type or the OFFSET FETCH clause, which was emulated using ROWNUM filtering, thus far.
In addition to the above, we're continuing our extended PL/SQL support by offering an emulation for the (de)serialisation of PL/SQL RECORD types. This is particularly interesting for everyone who used Oracle's now deprecated (12cR1) and removed (12cR2) JPublisher for PL/SQL bindings.
More info about this here: https://blog.jooq.org/use-jooq-to-read-write-oracle-plsql-record-types/
JSR-310 Java Time API support
We're now confident that we can support the "old" JDBC date time types and the "new" JSR-310 Java Time API types in parallel in a single API. With this in place, jOOQ now includes a <javaTimeTypes/> code generator configuration, that replaces the "old" JDBC date time types in generated code.
The upcoming patch releases for jOOQ 3.9.x will further improve the situation for TIME[STAMP] WITH TIME ZONE types in databases that do support them. Your continued feedback in this area is very welcome.
New DDL statements and clauses
As in every release, we've added support for tons of new DDL statements and clauses, including:
- A variety of RENAME statements
- The { CREATE | ALTER | DROP } SCHEMA statements
- The useful IF EXISTS clause for ALTER and DROP statements
- The useful IF NOT EXISTS clause for CREATE statements
- Support for partial indexes (CREATE INDEX .. WHERE)
- Support for ASC | DESC ordering in CREATE INDEX statements
- Support for Oracle's CONSTRAINT .. USING INDEX .. clause
- Support for IDENTITY columns
- Better support for constraint construction
Improved transactions API
The existing transactions API creates a new "scope" for each transaction, with a new, derived Configuration that contains that transactional scope (and a custom ConnectionProvider, not the user one). This was necessary from a design perspective to allow also for asynchronous transactions, which were introduced in jOOQ 3.8.
But if users can safely rely on ThreadLocal transaction semantics, the existing API that creates a new Configuration is too confusing. This is why jOOQ 3.9 now introduces the ThreadLocalTransactionProvider implementation that allows for the simpler transaction API to be used:
ctx.transaction(() -> { // Safe to re-use the "global" ctx here: ctx.insertInto(TABLE_A); ctx.update(TABLE_B); });
Besides, we now support a new TransactionListener SPI, which allows for hooking into the transaction lifecycle and execute stuff prior to beginning / committing or rolling back a transaction.
InformationSchema import and export
For a while now, we've supported the XMLDatabase in jooq-meta to generate code based on a SQL standard inspired XML format of your database schema: https://www.jooq.org/xsd/jooq-meta-3.5.4.xsd
This format is now also available to the jOOQ runtime library for importing and exporting schema meta information at runtime. In combination with the DSLContext.ddl() command, which was introduced in jOOQ 3.8, this makes for a very powerful schema import / export tool, which we're going to further improve in future versions.
Other minor improvements
- We've finally added support for PostgreSQL 9.5's ON CONFLICT clause.
- A new XMLGenerator allows for exporting a database schema to an XML document.
- A variety of new Java 8 style APIs, including "functional aliasing" and converter construction, and streaming.
- Mocking API improvements
- Lots of code generator and API improvements
Enjoy this exciting new milestone of jOOQ goodness!
API Diff:
See what's changed in terms of an API diff here: https://www.jooq.org/api-diff/3.8-3.9
Features and Improvements
#330 | Add code generation support for PL/SQL RECORD types |
#2303 | Implement a SQL parser |
#2607 | Add support for Oracle 12c's OFFSET .. FETCH clause |
#3146 | Add support for Oracle 12c IDENTITY types |
#3315 | Add code generation hooks to override Record, Pojo, and Interface getters and setters |
#3358 | Add the manual XML to GitHub |
#3906 | Allow for customising generated file headers |
#4164 | Generate varargs setters for array types on interfaces / records / pojos, etc. |
#4429 | Add <javaTimeTypes/> to code generator configuration to generate Java 8 java.time types instead of java.sql types |
#4512 | Add Table.as(String, Function<? super Field<?>, ? extends String>) to allow for "functional aliasing" |
#4794 | Add support for Catalog in code generation schema mapping |
#4919 | Add support for CREATE INDEX .. WHERE in PostgreSQL and SQL Server (filtered indexes) |
#5062 | Add support for IDENTITY columns in CREATE TABLE statements |
#5063 | Improve DSLContext.batchStore() Javadoc |
#5083 | Add support for ALTER SEQUENCE .. RENAME TO .. |
#5084 | Add support for ALTER VIEW .. RENAME TO .. |
#5085 | Add support for ALTER INDEX .. RENAME TO .. |
#5087 | Add support for ALTER TABLE, SEQUENCE, VIEW, INDEX IF EXISTS .. |
#5162 | Use DSLContext.connection() in internal code, rather than calling ConnectionProvider.acquire() directly |
#5238 | Format timestamp when formatting java.sql.Date, if time component is non-zero |
#5239 | Read and write the time component as well in Oracle's DATE type |
#5243 | Manual section showing jOOQ+JPA usage should take into account Binding and Converter |
#5244 | Add support for CREATE SCHEMA |
#5245 | Add org.jooq.Allow and org.jooq.Require annotation and a SQLDialectChecker using JSR-308 and the checker framework |
#5246 | Add an org.jooq.Allow.PlainSQL annotation and a PlainSQLChecker using JSR-308 and the checker framework |
#5247 | Deprecate SQLDialect.POSTGRESPLUS |
#5253 | Add support for Oracle COLLECT() |
#5255 | Add Dao.delete(P) overload (no varargs) to avoid potential generic warnings at the call site |
#5271 | Add SQLDialect.isFamily() |
#5276 | Add ParamMode, an enum to specify if a parameter is IN, OUT, or INOUT |
#5277 | Add support for CREATE SCHEMA IF NOT EXISTS |
#5278 | Add support for ALTER SCHEMA [ IF EXISTS ] .. RENAME TO |
#5279 | Add support for DROP SCHEMA [ IF EXISTS ] .. [ CASCADE | RESTRICT ] |
#5286 | Add more meaningful error handling when Maven code generator is not configured correctly |
#5289 | In the doc, part " 4.4.2. The CREATE statement " add a "nullable(false)" example |
#5295 | Implement Queries.toString() |
#5297 | Add InsertOnDuplicateStep.onConflict() for native PostgreSQL 9.5 ON CONFLICT support |
#5298 | Queries should extend Iterable<Query> and implement stream() |
#5301 | Display a warning in the generator logs for regexes that never match |
#5305 | Add support for CREATE INDEX .. ON (<expr> { ASC | DESC }, ...) |
#5311 | Add DSL.constraint() to create an unnamed (system named) constraint |
#5312 | Add SQLDataType.VARCHAR(length) and other methods for convenience |
#5313 | Add DSL.check() foreignKey(), primaryKey(), unique() to create unnamed (system named) constraints |
#5321 | Add support for POSITION(in, search, startIndex) |
#5327 | Allow for generating immutable interfaces (independently of POJOs) |
#5335 | Log a warning in the code generator if a table is reported to have two identity columns |
#5342 | Add nullable(false) in "The CREATE statement" part |
#5347 | Add XMLGenerator to produce an XML file containing meta information according to jooq-meta.xsd |
#5358 | Add support for INTERSECT ALL, EXCEPT ALL also in DB2 |
#5360 | Add <syntheticIdentities> regular expression to code generator configuration |
#5371 | Add an example project using Spark Java and Chart.js |
#5372 | Add Result.formatJSON(JSONFormat) to allow for different JSON formats |
#5373 | Add <syntheticIdentities> regular expression to code generator configuration |
#5377 | Add alternative TransactionProvider that implements ThreadLocal semantics |
#5378 | Add new TransactionListener SPI that hooks into the TransactionProvider lifecycle |
#5379 | Add convenience API in Configuration.set() and derive() to bypass the *Provider types |
#5384 | Add Settings.executeWithOptimisticLockingExcludeUnversioned |
#5389 | Enhance DSLContext.fetchFromJSON() to support new formats |
#5396 | Add Converter.andThen(Converter) and Converter.inverse() default methods |
#5398 | Add converter constructor Converter.of(Class<T>, Class<U>, Function<? super T, ? extends U>, Function<? super U, ? extends T>) |
#5413 | Add support for Oracle's RATIO_TO_REPORT() analytic function |
#5415 | Recommend using third party Gradle plugin for jOOQ instead of hand-written Groovy code |
#5418 | Add support for ALTER TABLE .. ADD CONSTRAINT .. USING INDEX (...) |
#5437 | Add support for loading the jooq-meta.xsd into org.jooq.Catalog / Schema / Table / etc. |
#5439 | Add Mock.of(Record), Mock.of(Result), Mock.of(MockResult...), Mock.of(int) |
#5443 | Document jOOQ 3.8 <forcedType/> configuration changes |
#5445 | Add support for Oracle 12c TRUNCATE .. CASCADE |
#5449 | Add Table.as(Table) to be consistent with Field.as(Field) |
#5452 | Add a big disclaimer to the Mock API not to mock an entire database |
#5460 | Add DSLContext.informationSchema(Catalog...), informationSchema(Schema...), informationSchema(Table...) to export jooq-meta.xsd format |
#5461 | Add DSLContext.ddl(Catalog) |
#5463 | Add org.jooq.Meta.getSequences() |
#5467 | Add Sequence.getCatalog() and Table.getCatalog() for convenience |
#5472 | Add <emptyCatalogs/> and <emptySchemas/> to the code generator configuration, to prevent generating of empty catalogs / schemas |
#5477 | Add <configurationFile> element to Maven code generation plugin, for external configuration |
#5485 | Add createView(String, Function<? super Field<?>, ? extends String>) where the Function receives Select columns as input |
#5487 | Add Table.as(String, BiFunction<? super Field<?>, ? super Integer, ? extends String>) to allow for "functional aliasing" (with column index) |
#5494 | Improve section of the manual explaining the plain SQL templating logic |
#5501 | Add Record.with(Field, T) for fluent setting of values on a Record |
#5508 | Add Record.intoStream() |
#5517 | Make JavaWriter.ref() methods public |
#5518 | Add inverse Type.xxx(Record) operations for Record.xxx(Type) methods |
#5522 | Add support for derived column lists with unnest() operator |
#5525 | Add code generator flag to turn off generation of tables |
#5526 | Add code generator flag to turn off generation of UDTs |
#5527 | Add code generator flag to turn off the generation of routines |
#5528 | Add code generator flag to turn off generation of sequences |
#5533 | Mention the possibility of running SELECT * by keeping an empty select() field list |
#5545 | Improve manual to explain Binding implementation in the context of static statements |
#5556 | Code generator should delete catalog and schema directories when no longer configured |
#5561 | Log warnings when users misconfigure forceType / customType elements |
#5562 | Add org.jooq.Log, an API that can be implemented by loggers, such as JooqLogger |
#5567 | Add Javadoc warnings on Field.in(Collection) and Field.in(T...) about cursor cache contention problems |
#5570 | Add debug information on exception stack traces |
#5575 | Add support for H2's TO_DATE() and TO_TIMESTAMP() function |
#5585 | Generated file header should read "this file is generated", not "this class is generated" |
#5600 | Add setting to enable IN list padding |
#5603 | Add TableLike.fieldStream() and other metadata Streaming methods |
#5616 | Added hint for m2e to behave |
#5618 | Further improve select() Javadoc for empty argument lists |
#5621 | Add FieldEscapeStep as a return type for Field.like(), such that the ESCAPE keyword can be used explicitly |
#5623 | Add Name.first() and Name.last() |
#5624 | Add Name.qualified() |
#5625 | Add Name.equalsIgnoreCase() |
#5626 | Add DSL.name(Collection<String>) |
#5627 | Add runtime support for PL/SQL RECORD types |
#5629 | Add DataType.isUDT() |
#5630 | DefaultBinding should TRACE log registered OUT parameters |
#5639 | MockFileDatabase ignores erroneous rows specification |
#5642 | Add DSL.localDate(), offsetDateTime(), offsetTime() to construct JSR-310 expressions |
#5643 | Add DSL.currentLocalDate() currentLocalTime() currentLocalDateTime() currentOffsetTime() currentOffsetDateTime() |
#5646 | Add DSL.trunc(LocalDate) etc |
#5647 | Add DSL.extract (LocalDate) etc. |
#5648 | Add DSL.toLocalDate () etc. |
#5657 | Explain the different org.jooq.Scope types in its Javadoc |
#5659 | Add clarification to OFFSET[DATE]TIME Javadoc that the behaviour is defined by the JDBC driver/database |
#5664 | Implement DefaultBinding.toString() |
#5681 | Add MockFileDatabase.nullLiteral() allowing to override the null literal in DSLContext.fetchFromTXT() |
#5690 | Document that only the Open Source Edition is hosted on Maven Central |
#5702 | Add support for PostgreSQL ON CONFLICT .. DO NOTHING |
#5706 | Code generator's <recordVersionFields/> setting does not match column |
#5709 | Add a DataType.identity() flag to specify that a data type is meant to be used as a SERIAL / IDENTITY type |
Breaking changes
#2684 | Rename org.jooq.scala package to org.jooq.scalaextensions because of potential collisions with the scala package |
#3943 | Custom Bindings cannot be applied on record version or timestamp columns |
#4168 | <outputSchemaToDefault/> generates "_" package name when generating multiple schemata |
#5233 | Remove DSL.field(Row[N]) to speed up client side compilation time |
#5320 | DSL.orderBy(Field...) returns WindowSpecificationOrderByStep instead of WindowSpecificationRowsStep |
#5395 | Fix covariance and contravariance on various Converter API usages |
#5589 | java.math.BigInteger should be generated for Oracle INTEGER columns |
Bug Fixes
#4965 | DateTimeParseException when parsing "lenient" OffsetDateTime format |
#5094 | StatementType.STATIC_STATEMENT is not applied to DSLContext.render(QueryPart) |
#5232 | Regression: Cannot select null values for enums |
#5249 | Bad inlining of Double.NaN in PostgreSQL |
#5251 | Oracle PIPELINED functions in packages are erroneously reported as AGGREGATE functions by the code generator |
#5256 | DAO.delete() should delete via UpdatableRecord.delete(), not via a bulk delete |
#5260 | Wrong update count when running UPDATE .. RETURNING in PostgreSQL and Firebird |
#5264 | PostgreSQL SMALLINT function arguments should always be cast explicitly |
#5268 | Compile error when a schema has the same name as a table within that schema |
#5280 | Bad Javadoc on dropTable() statements |
#5290 | Internal Cache$Key is not Serializable |
#5291 | Bad DataType.defaultValue() call generated for MySQL tables |
#5302 | Unmarshal warning : cvc-complex-type.2.4.b: The content of element 'target' is not complete. One of '{"jooq-codegen-3.8.0.xsd":encoding}' is expected. |
#5303 | Code generator aborts catalog browsing on SQL Server as soon as user is denied access to a single catalog |
#5307 | Avoid parsing ? in plain SQL if followed immediately by another operator-like character in PostgreSQL |
#5322 | Create constant empty arrays Field[0] and String[0] for faster toArray() calls |
#5323 | Wrong precision generated in automatic CAST for DB2 and other databases |
#5331 | Column default expressions using sequences are not treated as identity columns in H2 |
#5334 | Nested record generated when TABLE.COLUMN "overlaps" with a table called TABLE_COLUMN for MySQL |
#5349 | Wrong defaults for <tableValuedFunctions/> in jOOQ Open Source Edition |
#5356 | Incorrect order of HSQL column definition tokens: "DEFAULT" and "NULL" |
#5362 | Plain SQL batches produce wrong INFO messages about bind value count mismatches |
#5366 | Record.update() produces wrong update counts in HSQLDB |
#5368 | In HSQLDB, ALTER VIEW .. RENAME is not supported. Use ALTER TABLE .. RENAME instead |
#5380 | MySQL STRAIGHT_JOIN is not implemented correctly |
#5385 | Excessive WARN log level when a generated object has no name |
#5393 | Cannot apply Binding to PostgreSQL UDT arrays |
#5399 | Conversions.scala returns Option[_] instead of Option[T] or Option[U] where this is possible |
#5404 | Exceptions when calling Oracle functions / procedures with TABLE of TABLE type arguments |
#5408 | Optimistic locking doesn't work for PostgreSQL, Firebird |
#5416 | Bad update count on Oracle UPDATE .. RETURNING emulation |
#5424 | Don't escape Scala-style setter names produced by naming strategies in ScalaGenerator |
#5430 | Cumulative Earnings example in jOOQ-spark-chart-example is wrong |
#5432 | Fix the type-erasure issue for scala vararg helpers in org.jooq.scala.Conversions using scala.predef.DummyImplicit |
#5442 | Support default methods in DefaultRecordMapper.ProxyMapper |
#5446 | Unnecessarily costly query to check for Oracle version in code generation |
#5457 | "overriding method fields in class AbstractRecord" compilation error when using ScalaGenerator on tables containing columns like "fields", "configuration", etc. |
#5464 | Wrong @Support annotations on DSL.sequence() constructors |
#5470 | 3.8 manual is wrong about UPDATE .. RETURNING not being emulated |
#5481 | ResultImpl#intoMap produces an incorrect error message on duplicate key |
#5483 | Documentation of DSL#sql(String, QueryPart ...) does not mention parsing bind value placeholders ("?") |
#5495 | NotSerializableException thrown when AbstractXMLasObjectBinding is applied on a column |
#5509 | Cannot combine INSERT .. SELECT .. RETURNING with an arbitrary number of columns |
#5521 | Bad SQL generated for PostgreSQL when inlining arrays |
#5524 | Don't System.exit(-1) from within GenerationTool. Throw an exception instead |
#5536 | Missing reference to ResultQuery.fetchSize() in the manual |
#5540 | Bad predicate generated for INSERT .. ON DUPLICATE KEY IGNORE emulation in PostgreSQL 9.3 dialect |
#5547 | Work around an ojdbc7 driver bug producing a NPE for Oracle 12c INSERT .. RETURNING statements |
#5557 | Compilation error when generated catalog and one of its contained schemas have the same name |
#5559 | Add missing documentation for the <catalogVersionProvider/> configuration element |
#5569 | DataTypeException: Cannot convert from String to class [B when generated code contains VARBINARY type with default value |
#5573 | NullPointerException when generating Oracle AQs with payload types outside of the included schemas |
#5578 | Incorrect ambiguity warning when column name appears in 3+ joined tables |
#5583 | For generated code, change file header style from JavaDoc to regular comment |
#5584 | Fix all file headers to be regular comments, not Javadoc |
#5595 | Be more clear about excludes having priority over includes in code generation config manual section |
#5596 | Error on code generation when schema name is a Windows reserved name like CON, AUX |
#5597 | Code generator IOExceptions are not logged when error appears during closing of file |
#5607 | JPADatabase causes warnings |
#5608 | JPADatabase includes undesired INFORMATION_SCHEMA by default |
#5609 | Regression: Unspecified inputSchema no longer generates all schemata |
#5613 | Incorrect deserialisation of deeply nested PostgreSQL ARRAYs / UDTs |
#5614 | SchemaVersionProvider might cause deletion of schemas that were not updated |
#5617 | NullPointerException on fetchLazy().stream() / MockStatement.execute() returns false on empty results |
#5633 | Regression when reading PostgreSQL bytea[] type |
#5644 | DSL.currentDate() produces field name current_user |
#5649 | Trailing comma from ScalaGenerator when using schemaVersionProvider |
#5661 | Casting to SQLDataType.OFFSETTIME puts ojdbc connection in illegal state |
#5676 | [#5639] Fix MockFileDatabase ignores erroneous rows specification |
#5697 | jOOQ generated code contains deprecated calls |
#5701 | Work around PostgreSQL's limit of 32767 bind variables per statement |
#5704 | Escape HTML characters in generated JavaDoc |
#5707 | Fix typo for setting WindowSpecification |
#5708 | Function delegates window RANGE calls to ROWS |
#5715 | ArrayIndexOutOfBoundsException when fetching an unnamed column from SQL Server with plain SQL |
#5717 | CREATE SEQUENCE doesn't work in Derby, SQL Server, when names aren't quoted |
#5721 | jooq-codegen.xsd wrongly makes forcedType/name a mandatory element |
#5725 | Regression in MySQL's code generation prevents linking column types to enum classes |
#5727 | INSERT INTO table SELECT ... UNION ... renders bad SQL when column names are omitted and a plain SQL table is given |
#5728 | Emulate SELECT .. INTO .. also for HSQLDB using CREATE TABLE .. AS SELECT .. |
Version 3.8.0 - May 03, 2016
Version 3.8 is a collection of very useful little features and improvements that have been sitting on our roadmap for a long time:
More Java 8 and asynchronicity support:
One of Java 8's interesting new features is the monadic support for asynchronous operation composition: CompletionStage. jOOQ now features a variety of methods like DSLContext.transactionAsync(), ResultQuery.fetchAsync(), Query.executeAsync(), but also DBMS_AQ.dequeueAsync(), which allow for leveraging this new Java 8 API. In order to inject custom Executors into jOOQ, a new ExecutorProvider SPI has been added, defaulting to an implementation that uses the ForkJoinPool.
Kotlin integration:
While we were working on jOOQ 3.8, Kotlin 1.0 was released, a very exciting new JVM language by JetBrains. We've started experimenting with the jOOQ / Kotlin integration, and we've already added new methods to leverage Kotlin's syntax sugar: Record.get() and Record.set() (as synonmys for getValue() and setValue())
With these new methods, it is possible to use Kotlin's square bracket syntax to access and modify fields in a record:
val rec = fetchOne(BOOK); println(rec[BOOK.TITLE]); rec[BOOK.TITLE] = "10 SQL Tricks";
Stay tuned for more exciting Kotlin integration features in the near future!
The SQL Catalog type:
Most databases group objects in three hierarchy levels:
- Catalogs, which have several...
- Schemas, which have several...
- Tables (and other objects)
Specifically, in SQL Server, it is possible to select data from objects across several catalogs. jOOQ 3.8 finally formally supports the org.jooq.Catalog type both in the code generator as well as in the runtime.
New DDL features:
Schema migrations and initial database setups become an increasingly useful feature for many jOOQ users. In each release, we're adding support for additional statements and clauses of existing statements. jOOQ 3.8 now supports:
- 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
In addition to the above statements, we now allow for generating a set of DDL commands from a Schema or Table reference. This is very useful e.g. to recreate an Oracle schema on an H2 in-memory test database.
Code generator improvements:
Among many other improvements, we've simplified data type conversion and binding configurations. This essentially means: Much less XML for the same feature set!
Also, we've added additional flags that help maintaining more fine-grained control over which artefacts you really want to generate.
General notes:
We have once more postponed thorough JSR 310 (java.time) API support. This feature addition is one of our users' most wanted. We're aware of this and sorry we still couldn't deliver it. The risks of getting things wrong in terms of backwards-compatibility are high, and we don't want to get this wrong.
We have changed some internals, which may affect those of you who heavily extend jOOQ. In particular, the deprecated QueryPartInternal.toSQL() and bind() are no longer overridable. Please move your implementation to the accept() method, which was added in jOOQ 3.4. Our main benefit from this incompatible change is a substantial performance improvement, as we can now traverse the jOOQ QueryPart expression tree only once in order to collect the SQL string and the bind variables, which leads to a roughly 40% faster SQL rendering in benchmarks!
All in all, this is an exciting and big new release with tons of little new features that you won't want to miss once you have upgraded! Details below.
Enjoy!
API Diff:
See what's changed in terms of an API diff here: https://www.jooq.org/api-diff/3.7-3.8
Features and Improvements
#1068 | Add integration tests for DSLContext.loadInto() when using only plain SQL objects |
#1859 | Add Setting to always fetch all record data after INSERT or UPDATE |
#2032 | Add code generation support for the new org.jooq.Catalog type |
#2211 | Change Record.getValue() and setValue() to get() and set() |
#2438 | Add ParamType Param.paramType() to indicate whether a parameter is INDEXED, NAMED, INLINED |
#2928 | Mapping tables based on regular expressions |
#3065 | Add performance regression tests |
#3073 | Distribute commercial jOOQ artifacts under a different groupId to avoid conflicts |
#3160 | Add Queries DSLContext.ddl(Schema), ddl(Table) and others to re-generate known artefacts |
#3254 | Add support for PostgreSQL materialized views |
#3330 | Allow custom quote character/no quote character when exporting to CSV |
#3482 | Add flags to the code generator to turn on / off generation for tables, views, packages, procedures, udts, etc. |
#3570 | Add KeepNamesGeneratorStrategy to keep generated identifiers as they are in the database |
#3691 | Improve API to create CASE expressions with arbitrary numbers of arguments |
#3761 | Add code generator configuration to specify a log level threshold |
#3852 | Add DataType.defaultValue(Field<T>) to allow for setting DEFAULTs in DDL statements |
#3942 | Add support for PostgreSQL functions returning single table records |
#4050 | Allow for specifying constraints with CREATE TABLE statements |
#4124 | Add <username/> as a synonym for <user/> in the code generation configuration |
#4155 | Add support for PL/SQL BOOLEAN types |
#4375 | Add support for CREATE TEMPORARY TABLE also in MySQL / MariaDB |
#4435 | Add DSLContext.transactionAsync(TransactionRunnable) and transactionResultAsync(TransactionCallable) |
#4480 | Emulate H2's MERGE statement for MySQL, MariaDB, and PostgreSQL 9.5 |
#4500 | Add a short section to the manual explaining how to configure jOOQ with JPA or Vertabelo |
#4501 | Add .fetch() and .execute() also to historic manual versions |
#4517 | Allow to configure the output file encoding in the code generator |
#4550 | Add support for property expressions in the code generator's standalone configuration |
#4568 | Add support for the PostgreSQL MODE() ordered-set aggregate function |
#4598 | Add <userType/>, <converter/>, <binding/> in <forcedType/>, to allow for working without <customType/> |
#4619 | Let SQLTable constructor pass SQL string to AbstractTable parent constructor |
#4620 | Change error message when jOOQ-meta database type could not be found |
#4663 | Add DSL.val(X), value(X), and inline(X) overloads for all common types |
#4676 | Add SelectFromStep.from(Name) and similar convenience methods |
#4677 | Add type safe overloads DSL.with(String, String, String) that will expect Select<? extends Record2<?, ?>> |
#4687 | Add ResultQuery.fetchStream() as a alias for stream() |
#4688 | Add a Javadoc comment to DataType#convert() linking to Convert#convert() for details |
#4693 | Add DSL.toDate(value, format) and DSL.toTimestamp(value, format) |
#4696 | Relax API contracts on DAOImpl by removing final keyword on methods |
#4715 | Allow to specify the newline character for Result.formatCSV() |
#4721 | Add Javadoc examples to DSL.using(String), showing proper use with try-with-resources |
#4724 | Add Table.eq(Table<R>) and Table.ne(Table<R>) |
#4729 | Emulate DSL.count(Table) and countDistinct(Table) for all other dialects |
#4730 | Recognise pgjdbc-ng JDBC URL in JDBCUtils.dialect(String) |
#4731 | Add Javadoc warning to Table.equals() to help prevent accidental usage |
#4735 | Add DSL.condition(Record) for Query By Example (QBE) predicate building support |
#4746 | Allow for specifying empty string as formatCSV()'s nullString / emptyString |
#4752 | Improve documentation of using jOOQ's code generator with ant |
#4753 | Add Settings for default naxRows, fetchSize, queryTimeout and other values |
#4756 | Add section to the manual documenting how to include the commercial jOOQ distribution in a Maven build |
#4761 | Add MySQL IFNULL() support as a synonym for NVL() |
#4763 | Deprecate on(Boolean), where(Boolean), having(Boolean), etc. |
#4769 | Improve TableLike.field(Field) Javadoc |
#4784 | Add support for OFFSET .. LIMIT in addition to LIMIT .. OFFSET |
#4785 | Add support for OFFSET without LIMIT |
#4791 | Upgrade scala dependency to 2.10.6 |
#4792 | Add Schema.getCatalog() and render the catalog in SQL |
#4795 | Add Setting to turn off rendering catalog at runtime |
#4796 | Add Context.qualifyCatalog() to allow for locally qualifying names without catalog |
#4797 | Document caveat when using Gradle XML Markup generator with some elements |
#4799 | Add a note to the manual about the Gradle / Groovy MarkupBuilder caveat related to some elements |
#4801 | Add DEQUEUE_OPTIONS_T.wait(int) to support timeout-based waits on Oracle AQ |
#4811 | Add source code in original form to .zip, such that users can build jOOQ right away |
#4818 | Add org.jooq.CSVFormat: A parameter object to replace the existing formatCSV overloads |
#4825 | Add support for Oracle table-valued functions |
#4827 | Add CatalogVersionProvider |
#4833 | Generate standalone function call for table-valued functions |
#4834 | Add Context.declareAliases as a flag to indicate whether alias declaration generating QueryParts are allowed to do so |
#4837 | Add DefaultConnectionProvider.setReadOnly() and isReadOnly() |
#4838 | Add code generation flag <tableValuedFunctions/> to turn off generation of table-valued functions |
#4839 | Rename Generator.fullyQualifiedTypes() to generateFullyQualifiedTypes() for naming consistency |
#4841 | Add code generation support for column DEFAULT values |
#4842 | Add support for RANGE clause in window functions |
#4847 | Improve Javadoc's of Loader API's various fields() methods |
#4848 | Add internal API to configure indentation of generated code |
#4855 | Remove final keyword on JavaGenerator methods |
#4857 | Add a chapter to the manual about in-memory importing |
#4858 | Add a section to the manual about importing JSON |
#4859 | Deprecate LoaderJSONOptionsStep.ignoreRows() |
#4868 | Generate 4 spaces in Java or 2 spaces in Scala instead of tabs in generated code by default |
#4869 | Generate schema and catalog references in order to fully qualify tables |
#4873 | Add Firebird 3.0 support for MERGE |
#4874 | Add Firebird 3.0 support for window functions |
#4879 | Add generateGlobalCatalogReferences() and generateGlobalSchemaReferences() flags to code generator |
#4889 | Update copyright to 2016 |
#4891 | Accept DataSource in GenerationTool, in addition to Connection |
#4892 | Add sections to the manual explaining how to use JPADatabase |
#4893 | Add a tutorial section to the manual showing how to use jOOQ with Kotlin |
#4897 | Add sections to the manual explaining how to use XMLDatabase |
#4901 | Add UniqueKey.getName() and ForeignKey.getName(), and generate this info in Keys.java |
#4903 | Emulate EVERY() with MAX() rather than with COUNT() |
#4904 | Add DataAccessException.sqlStateClass() and sqlStateSubclass() |
#4906 | Add manual and Javadoc URL mapping for /current/ = /latest/ |
#4907 | Add DSLContext.fetchFromHTML() to convert an HTML table into a jOOQ Result |
#4914 | Add support for CREATE UNIQUE INDEX |
#4915 | Add UniqueKey.isPrimary() |
#4916 | Implement Key.equals() and hashCode() for all Key types |
#4918 | Add Key.constraint() and improve Key.toString() accordingly |
#4931 | Add a section to the manual explaining the use of dynamic SQL |
#4936 | Add support for CREATE TABLE IF NOT EXISTS |
#4952 | Add flag to turn off generation of database links |
#4954 | Add flag to turn off generation of queues |
#4967 | Add support for CREATE VIEW IF NOT EXISTS |
#4968 | Add support for CREATE [ UNIQUE ] INDEX IF NOT EXISTS |
#4969 | Add support for CREATE SEQUENCE IF NOT EXISTS |
#4974 | Add ExecuteListener to jOOQ-meta logging a warning when queries take longer than 5s |
#4991 | Deprecate Param.setValue(), setConverted(), setInline() |
#4997 | Add DSL.recordType(Field<?>[]) |
#4999 | Add StopWatch.splitXXX(message, threshold) to log a message only if a threshold has been passed |
#5009 | Generate the JPA GeneratedValue annotation on identity columns |
#5011 | Add mergeInto(Table).columns(...).values(...) as an alternative syntax for H2's MERGE |
#5012 | Add CompletionStage<Result<R>> ResultQuery.fetchAsync() and fetchAsync(Executor) |
#5014 | Add Query.executeAsync() and executeAsync(Executor) |
#5015 | Add DBMS_AQ.dequeueStream() to create an Oracle AQ Stream |
#5016 | Add DBMS_AQ.dequeueIterable() to create an Oracle AQ Iterable |
#5021 | Add DBMS_AQ.dequeueAsync() to create an Oracle AQ CompletionStage |
#5022 | Clarify fetch() Javadoc with respect to nullable results |
#5038 | Add an example to the manual showing how to use the maven ant plugin |
#5040 | Add a new ExecutorProvider Configuration.executorProvider() SPI for asynchronous tasks |
#5046 | Issue a warning when Record.field(String) runs into ambiguous columns |
#5055 | Add CreateTableColumnStep.column(Field<?>) for convenience |
#5056 | Add org.jooq.Queries, a wrapper for Query[] |
#5057 | Replace Collection.toArray(new T[size]) calls by Collection.toArray(new T[0]) calls |
#5058 | Add DSLContext.batch(Queries) and other overloads where Query[] or Collection<? extends Query> are accepted |
#5059 | Add CreateTableColumnStep.columns(Field<?>...) |
#5061 | Improve formatting of DDL statements |
#5064 | Improve formatting for MySQL's ON DUPLICATE KEY UPDATE clause |
#5065 | Make all internal classes final if they're not intended for extension |
#5066 | Add CreateTableColumnStep.column(Name, DataType<?>) |
#5067 | Add AlterTableStep.alter[Column](Name), add[Column](Name), drop[Column](Name) |
#5072 | Add default implementations for SPIs, accepting functional event handlers |
#5077 | Add more examples for using RVE IN predicates |
#5081 | Add support for ALTER TABLE .. RENAME TO .. |
#5082 | Add support for ALTER TABLE .. RENAME COLUMN .. TO .. |
#5086 | Add support for ALTER TABLE .. RENAME CONSTRAINT .. TO .. |
#5093 | Implement INSERT .. ON DUPLICATE KEY IGNORE using INSERT .. ON CONFLICT in PostgreSQL 9.5 also when using SQLDialect.POSTGRES |
#5105 | DEBUG-Log exceptions in LoggerListener |
#5113 | Remove Vertabelo Plugin from jOOQ-meta-extensions |
#5117 | Overload internal Tools.field(T) method with concrete T types |
#5118 | Log error in JDBCUtils.safeFree() methods, in case of ignored exception |
#5122 | Improve Javadoc for Loader.loadArrays() |
#5123 | Add LoaderSourceStep.loadArrays(Stream<? extends Object[]>) and loadRecords(Stream<? extends Record>) |
#5124 | Add a chapter to the manual about case-insensitivity (e.g. in filtering, grouping, sorting) |
#5144 | Improve CASE expression formatting |
#5145 | Add LoaderXXXStep.fields(FieldMapper) for better mapping between source and target fields |
#5154 | Add support for mapping Record1<String> to Enum by Enum.valueOf() in DefaultRecordMapper |
#5161 | Add logback.xml file to jOOQ-spring-boot-example to enable DEBUG logging per default |
#5163 | Add UpdatableRecord.refresh(Collection<? extends Field<?>>), store(Collection), insert(Collection), update(Collection) |
#5164 | Implement BindingSetStatementContext.toString() for improved debugging |
#5190 | Support UPDATE and DELETE RETURNING for Oracle using PL/SQL RETURNING .. INTO |
#5192 | Add SafeVarargs annotation to DSL.values() constructor methods |
Breaking changes
#3323 | Make QueryPartInternal.toSQL() and bind() final in favour of the new accept() method |
#4388 | Compilation errors when applying <customType/> for PostgreSQL array types |
#4650 | Collect bind variables while generating SQL, instead of traversing the AST twice |
#4658 | Let DSL.zero(), one(), two() return Param instead of Field |
#4815 | Relax bound from <R extends TableRecord<R>> to <R extends Record> for DSLContext.loadInto() |
Bug Fixes
#2549 | SQLDialectNotSupportedException when calling DSL.val(EnumType) |
#2995 | INSERT INTO table SELECT ... renders bad SQL when column names are omitted and a plain SQL table is given |
#3225 | Performance bottleneck in MetaFieldProvider when fetching unknown plain SQL fields |
#3354 | Fix manual's sections about plain SQL. Avoid referencing to toSQL() and bind() directly |
#3935 | InternalVisitListener accounts for a lot of CPU load |
#4131 | DSLContext.extractBindValues(QueryPart) doesn't report the implicit bind values from plain SQL QueryParts |
#4427 | ScalaGenerator generates Java code for MySQL / PostgreSQL enum types |
#4624 | Compilation error in generated code when column is of type "TIMESTAMP WITH TIME ZONE" in Oracle |
#4626 | Zero-length DAO source files generated for non-updatable tables |
#4634 | Significant CPU overhead in CursorImpl$CursorIterator#fetchOne() due to frequent HashMap access |
#4637 | Regression in Table.onKey(ForeignKey) with multiple joins |
#4638 | Misleading ReferenceImpl.toString() implementation |
#4642 | Significant schema mapping initialisation overhead when schema mapping isn't even used |
#4646 | Significant overhead from Scope.data() Map access |
#4651 | Significant overhead caused by AbstractContext's internal ArrayDeque stacks that created even if there are no VisitListeners |
#4659 | Significant overhead caused by type lookup when using DSL.val(T) or DSL.inline(T) in org.jooq.impl.Limit |
#4664 | Inefficent initialisation of SortFieldList and other QueryPartLists |
#4668 | Significant overhead caused by check if FROM clause is needed |
#4672 | Too many context objects are created when generating SQL |
#4678 | Plain SQL version SelectJoinStep.straightJoin() is missing @PlainSQL annotation |
#4680 | Manual 3.6+ makes use of deprecated fieldByName() and tableByName() methods |
#4682 | Code generation for Postgres DBs assumes column data type to be in same schema as table |
#4685 | Manual's "More info about how to read this manual" always refers to 3.4 version of the manual |
#4686 | Incomplete overloading of SelectJoinStep.straightJoin() |
#4692 | Use correct term for "ordered-set aggregate function" in Javadoc and manual |
#4708 | Wrong enum type referenced from UDT, when the same enum type exists in different schemas in PostgreSQL |
#4712 | Cannot call standalone PostgreSQL function with enum array return type in non-public schema |
#4737 | Documentation bug: Deprecation remark on fieldByName(Class, String...) points to wrong substitute |
#4740 | ClassCastException when using DSL.any() in a Condition Field |
#4744 | Record getter and setter names are generated with Mode.DEFAULT rather than Mode.Record |
#4749 | Regression in AbstractParam throwing StackOverflowError when calling UDTRecord.toString() |
#4755 | Manual typo. Manual still referring to "T_" prefix in tables |
#4762 | org.jooq.Meta must not cache DatabaseMetaData in order not to violate the ConnectionProvider contract |
#4771 | Confusing SQLDialectNotSupportedException when passing wrong arguments to DSL.nvl() function, and others |
#4772 | Extremely slow mapping Record.into(ProxyableInterface.class) |
#4773 | DefaultRecordMapper is not thread safe when mapping proxyable interface |
#4780 | OracleDSL.DBMS_AQ.enqueue() and dequeue() produce wrong syntax depending on parameters that are passed |
#4782 | OracleDSL.DBMS_AQ.dequeue() does not return any MESSAGE_PROPERTIES_T values |
#4783 | Unnecessary SQL exception logged in code generator |
#4798 | Manual typo: Update returning doesn't return update count |
#4800 | Oracle Functions accepting returning PL/SQL-only types are not "SQL usable" |
#4802 | Oracle views with dollar sign '$' in them are not generated |
#4806 | CREATE VIEW statement fails when it contains bind variables |
#4820 | Oracle LONG and LONG RAW columns cause "Stream has already been closed" exception when not placed in first position |
#4829 | Generated convenience methods Routines.f() have misleading Javadoc |
#4840 | <types/> is a regular expression. The manual should make an indication about this |
#4843 | Missing @Support annotations for Vertica and window functions and other API elements |
#4849 | Wrong emulation of SINH() and other hyperbolic functions for Vertica |
#4851 | Wrong emulation of bitwise XOR for Vertica |
#4863 | Manual section about importing CSV erroneously refers to AUTHOR table rather than BOOK table |
#4870 | SQLDialect.POSTGRES_x_x Javadoc is wrong |
#4880 | Escaped block comment inside of Scaladoc causes compilation error |
#4883 | Table valued functions generate bad Scala code |
#4890 | Typo in doc, part "3.4.4. Using jOOQ with Flyway" |
#4910 | Bad SQL generated for CREATE TABLE AS SELECT .. FROM (SELECT ..) in SQL Server |
#4920 | Generated functions without parameter names produce malformed SQL |
#4922 | A negligible amount of CPU is spent in String.indexOf() because of identifier escaping |
#4926 | A small amount of CPU time is wasted on Operator.name().toLowerCase() |
#4935 | Convert.convert(long, Instant.class) shouldn't pass by LocalDateTime |
#4939 | SQLFeatureNotSupportedException thrown in some (unsupported) SQLDialects when initalizing MetaDataFieldProvider |
#4953 | Very slow code generation in Oracle when existing DB Links are not available |
#4955 | ClassCastException when applying schema mapping on procedures and types in Oracle |
#4957 | NullPointerException in ArrayRecord.toString() when ArrayRecord is not attached |
#4964 | Type handling issue when using a custom type with a Postgres UDT field |
#4966 | Standalone calls to Oracle pipelined functions aren't possible |
#4970 | PostgreSQL code generation does not stably order overloaded routines |
#4976 | jOOQ's internals should not call QueryPartInternal.accept(Context), but Context.visit(QueryPart) instead. |
#4977 | HSQLDB does not support bind variables in DDL statements |
#4981 | Wrong SQL generated for CREATE TABLE .. AS SELECT in HSQLDB |
#4985 | Utils.executeImmediate() doesn't work when inlined SQL contains apostrophes |
#4992 | Support for emulating VALUES clauses in H2 is inefficient |
#4996 | DateAsTimestampBinding doesn't work as documented in the manual |
#5004 | Misleading Javadoc on DSL.table(String) |
#5010 | Remove push tag from repository |
#5017 | NullPointerException when using MockConnection with DSLContext.transaction() |
#5024 | Wrong implementation of internal SortFieldList.nulls() |
#5028 | Slow routine overload index calculation in PostgreSQL's code generator |
#5042 | Record[N].values(T1, T2, ..., TN) is not implemented |
#5051 | TableAlias does not delegate getIdentity(), getPrimaryKey(), getKeys(), getRecordVersion(), getRecordTimestamp() calls to aliased table |
#5068 | SQL Server 2008 SELECT DISTINCT .. LIMIT .. OFFSET emulation does not keep ORDER BY semantics in complex queries |
#5088 | Bad deserialisation of PostgreSQL UDTs that contain boolean attributes |
#5089 | Wrong SQL generated for multi row INSERT when ON DUPLICATE KEY IGNORE is emulated |
#5095 | ScalaGenerator produces an invalid import expression for SQL array types |
#5097 | Table.getPrimaryKey() does not work with SQLite's Xerial JDBC driver, when primary key column contains upper-case characters |
#5103 | Tables referencing object arrays generate Record array in POJOs, rather than POJO array |
#5104 | Bad HTML in ExecuteListener.outStart() Javadoc |
#5106 | Result.formatXXX() methods should flush Writers to prevent data loss |
#5128 | Don't generate javax.validation.NotNull for defaulted columns |
#5134 | OracleConnection Class not found when jOOQ runs in OSGi and ARRAY types are bound |
#5140 | DSL.currentTimestamp() cannot be used as a default value for a column, via alterTable |
#5150 | Settings.backslashEscaping is not applied to LIKE .. ESCAPE clause |
#5158 | FILTER (WHERE ...) and OVER() is not applied to PostgreSQL ARRAY_AGG() |
#5167 | Possible NPE when calling InsertImpl.set(Field, Select) with a null Select |
#5174 | NullPointerException when calling Query.getSQL() on an unattached Query |
#5180 | DefaultBindings for OffsetTime and OffsetDateTime handle negative offsets |
#5182 | Meta Table.getKeys() returns an empty list containing "null", if a table has no primary key |
#5186 | Excessive log level when ignoring foreign key referencing an out-of-scope schema |
#5193 | PostgreSQL timestamp deserialisation loses millisecond precision, when timestamp is contained in an array of composite types |
#5202 | MySQL unsigned data types in stored procedures and functions are not captured correctly by jOOQ's code generator |
#5212 | MetaDataFieldProvider should not catch SQLFeatureNotSupportedException from ResultSetMetaData calls |
#5225 | Results.clear() does not remove update counts |
Version 3.7.0 - October 8, 2015
jOOQ 3.7 means Java 8
This release is great news for all of you working with Java 8. From jOOQ 3.7 onwards, we officially support Java 8 and its new APIs, including Stream, Optional, FunctionalInterface, as well as Java 7 features like AutoCloseable, SafeVarargs, and many more. The newly introduced Stream type is a very suitable match for a JDBC ResultSet, or a jOOQ Cursor, given that jOOQ already knows all the type information on individual streaming elements.The new paradigm that has reached the JDK with Java 8 is functional programming. SQL and functional programming are a perfect match for data-driven algorithms that aim for transforming values with functions. We've blogged about this in the past:
- https://blog.jooq.org/java-8-friday-no-more-need-for-orms/
- https://blog.jooq.org/java-8-friday-more-functional-relational-transformation/
If you're still on an older version of Java, we'll continue supporting Java 6 for our commercial customers, where we offer a Java 6 build and a Java 8 build.
jOOQ 3.7 means even more Big Data: Azure, Redshift, Vertica
SQL is the language of Big Data. When you have billions of rows in your table, a column store might seem more suitable than a row store ("NewSQL"), and with SQL, you can optimally query, transform, and aggregate your data. jOOQ fits this model perfectly!jOOQ 3.6 added support for SAP HANA. jOOQ 3.7 now also adds support for SQL Azure, Redshift, and Vertica. With these additions, jOOQ is the best choic for your Java / Big Data application.
jOOQ 3.7 adds support for PostgreSQL 9.5
PostgreSQL is advancing fast. We've now added support for their next major release, which includes GROUPING SETS, UPSERT, SKIP LOCKED, ROW UPDATES and many other featuresOther minor improvements
As always, the convenience of the jOOQ API has greatly increased, having added new overloads for popular methods as well as new access paths to existing functionality.We've also added support for new JOIN types, such as LEFT SEMI JOIN (EXISTS), LEFT ANTI JOIN (NOT EXISTS), or MySQL's STRAIGHT_JOIN syntax.
Writing PL/SQL? Working with TABLE and OBJECT types has now gotten even simpler, and we've also added support for Oracle database links.
API Diff:
See what's changed in terms of an API diff here: https://www.jooq.org/api-diff/3.6-3.7
Features and Improvements
#659 | Add support for SQL Azure |
#1206 | Add Table.leftAntiJoin(Table).on(...) and Table.leftSemiJoin(Table).on(...) to simplify usage of [NOT] EXISTS / IN |
#1350 | Add support for the VERTICA database |
#1364 | Generate toString() on POJOs |
#1503 | Emulate INSERT .. ON DUPLICATE KEY IGNORE in remaining dialects, using INSERT .. SELECT WHERE NOT EXISTS |
#1711 | Add <K, V> Map<K, List<V>> ResultQuery.fetchGroups(Class<K>, Class<V>) and many others |
#1843 | Add section to the manual showing how to use jOOQ with JPA native query |
#2728 | Add support for Amazon Redshift |
#2920 | Emulate CROSS APPLY as LATERAL JOIN for PostgreSQL |
#3082 | Let generated POJOs reference Java array types, instead of ArrayRecords |
#3645 | Let jOOQ require Java 8 - Keep supporting Java 6 in commercial editions |
#3772 | Publish manual also in EPUB format |
#3783 | Add Field<String> DSL.currentSchema() |
#3887 | Support SAP HANA UPSERT |
#3955 | Add a flag to DefaultTransactionProvider to disable the support for nested transactions via savepoints |
#4006 | Add <T> Field<T[]> array(Field<T>...) |
#4016 | Add support for the SQL Standard NTH_VALUE window function |
#4113 | Add Field<?>[] { Cursor | Record | RecordType | Result | Row | TableLike | UDT }.fields( { Field<?>... | int... | String... } ) for convenience |
#4133 | Add table name to formatJSON(), formatXML() export formats |
#4212 | Add LoaderSourceStep.loadRecords(Iterable<? extends Record>) |
#4218 | Add LoaderSourceStep.loadArrays(Iterable<? extends Object[]>) |
#4222 | Generate a Links.java file containing org.jooq.Link references |
#4239 | Add Result.formatCSV(boolean) (and related convenience methods) to avoid header |
#4252 | Provide an out-of-the-box mapping between jOOQ's SQLDialect and Spring dialect names |
#4253 | Provide an out-of-the-box mapping between jOOQ's SQLDialect and Hibernate dialect names |
#4254 | Add support for default routine parameters in PostgreSQL |
#4255 | Add the PostgreSQL VOID data type |
#4271 | Add implicit ScalaResultQuery type to add additional functionality to ResultQuery for Scala users |
#4272 | Add missing <E> E ResultQuery.fetchAny(RecordMapper<? super R, E>) |
#4273 | Add implicit ScalaDSLContext type to add additional functionality to DSLContext for Scala users |
#4275 | Remove VisitListener's "experimental" disclaimer from Javadocs |
#4281 | Add support for MySQL's STRAIGHT_JOIN |
#4283 | Plain SQL queries should read the ResultSetMetaData.getTableName() property if it is available, and produce DSL.field(Name) for better disambiguation |
#4284 | Add { Cursor | Record | RecordType | Result | Row | TableLike | UDT }.field(Name) to extract qualified fields from a row type |
#4299 | Add support for PostgreSQL 9.5 |
#4304 | Add support for INTERSECT ALL, EXCEPT ALL clauses |
#4305 | Add support for the PostgreSQL ROWS FROM () clause |
#4307 | Add an example using the Spark Framework |
#4312 | Add various fetchOptional() methods |
#4336 | Let Cursor and Query extend AutoCloseable |
#4337 | Add Stream<R> ResultQuery.stream() |
#4338 | Add support for java.time |
#4339 | Add DSLContext.fetchStream(...) similar to the existing DSLContext.fetchLazy(...) API |
#4340 | Add Cursor.stream() |
#4363 | Replace using the term "simulate" by "emulate" in all documentation |
#4365 | Document ALTER TABLE .. ADD CONSTRAINT statement in the manual |
#4366 | Add on(Boolean), where(Boolean), having(Boolean), etc. |
#4376 | Translate INSERT .. ON DUPLICATE KEY IGNORE to SQLite's INSERT OR IGNORE |
#4379 | Upgrade Scala dependency from 2.10.4 to 2.10.5 |
#4380 | Make dialect-specific DSL constructors protected to allow further subtyping |
#4398 | Add "t" and "f" to org.jooq.tools.Convert's TRUE_VALUES and FALSE_VALUES |
#4407 | Moved jOOQ Spring Boot to dedicated configuration class. |
#4408 | Document escaping of curly braces in plain SQL templates |
#4413 | Explain in the manual why LIMIT .. OFFSET emulation for Oracle uses ROWNUM instead of ROW_NUMBER() OVER() |
#4416 | Add a remark to the VisitListener Javadoc that implementors should be wary of performance implications |
#4421 | Create sample data for manual sample database |
#4422 | Update jOOQ 3.7 manual and use try-with-resources statements instead of explicit close() calls |
#4424 | Use ArrayDeque as a stack, internally, instead of java.util.Stack |
#4426 | Add <T> T DSLContext.fetchValue(TableField<?, T> field) |
#4431 | Add an about file to the deliverable and to the manual, as specified in the transfer of rights agreement |
#4432 | Add support for java.time in Convert |
#4438 | Add support for CUBRID's { CREATE | DROP } SERIAL statement |
#4443 | Add support for DROP { TABLE | VIEW } IF EXISTS in CUBRID |
#4450 | Add support for ALTER TABLE MODIFY in CUBRID |
#4451 | Add DSLContext.fetchFromCSV(boolean) to allow for fetching header-less CSV data |
#4456 | Implement Table.field(x).getDataType().nullable() for tables obtained via org.jooq.Meta |
#4458 | Add support for Oracle DB links via Table.at(Link), Table.at(Name), Table.at(String) |
#4463 | Add support for passing ROW value expressions to ROLLUP(), CUBE(), and GROUPING SETS() |
#4464 | Emulate H2's MERGE statement for PostgreSQL 9.5 |
#4465 | Add new FieldOrRow type to provide a common super-type for Field<?> and Row |
#4470 | Add <springAnnotations/> code generation configuration to generate Spring annotations on select objects |
#4475 | Add UpdateSetFirstStep.set(RowN, Select<?>) |
#4476 | Issue a warning when Record.field(Field) runs into ambiguous columns |
#4479 | DSLContext should implement AutoCloseable, in case it was constructed via DSL.using(String) |
#4489 | Upgrade Hibernate dependency in jOOQ-meta-extensions to 5.0 |
#4502 | Add org.jooq.Results extends List<Result<Record>> and return this type on fetchMany() calls |
#4505 | Add Maven plugin skip property |
#4508 | Add DSL.condition(Map<Field<?>, ?>) to construct a predicate from a field=>value map |
#4511 | Log a warning when a user accidentally sets the fetchSize with autoCommit == true in PostgreSQL |
#4515 | Emulate POSITION() with INSTR() in SQLite |
#4523 | Add the @SafeVarargs annotation to all methods taking Field<T>... and similar arguments |
#4524 | Add missing DSL.field(String, DataType, QueryPart...) method |
#4530 | Add support for boolAnd(Condition), boolAnd(Field<Boolean>), boolOr(Condition), boolOr(Field<Boolean>) |
#4535 | Make existing join() a synonym for a new innerJoin() method |
#4536 | Make existing { left | right } OuterJoin() a synonym for a new { left | right }Join() method |
#4537 | Let GenerationTool accept multiple argument configurations |
#4538 | Add Constants.XSD_EXPORT and NS_EXPORT |
#4552 | Add DSLContext.connection(ConnectionRunnable) |
#4553 | Add @FunctionalInterface annotation to all relevant callback types |
#4555 | Ensure batches are sent |
#4562 | Do not escape dot in table names during code generation, but use capital case after it |
#4565 | Add Optional support to org.jooq.tools.Convert |
#4566 | Let ArrayRecord<E> extend List<E> |
#4587 | Add Schema ArrayRecord.getSchema() |
#4591 | .zip deliverable should contain a project folder inside of the .zip file |
#4594 | Add DSLContext.query(SQL) etc |
#4597 | Log warning when <forcedType/> doesn't have any matching SQLDataType or <customType/> |
#4600 | Add support for plain SQL APIs via Scala string interpolation |
Breaking changes
#4326 | CREATE SEQUENCE statement lets sequences start with MIN_VALUE, not 1 in Derby |
#4423 | Relax type constraint of DSL.shl() and DSL.shr() |
#4459 | Result.formatHTML() doesn't escape HTML content, which might produce XSS vulnerabilities |
#4488 | Relax bound on <T> for Table.getIdentity() from <? extends Number> to <?> |
Bug Fixes
#2364 | Multi-Result queries may mix ResultSets with update counts. jOOQ doesn't correctly check both in fetchMany() |
#2529 | Cannot combine INSERT .. SELECT with INSERT .. ON DUPLICATE KEY .. due to DSL API flaw |
#2870 | TableOnStep.onKey() generates wrong join condition when left-hand side contains aliases |
#3707 | UDTRecord.toString() doesn't correctly serialise attribute values |
#3779 | Cannot combine INSERT ... SELECT with RETURNING |
#4162 | Malformed record literal when using PostgreSQL array of user-defined types |
#4224 | ORA-00904: "SYS"."ALL_PROCEDURES"."OBJECT_ID": invalid identifier when using the code generator with Oracle 10g |
#4225 | ScalaGenerator logs that it generates XXX.java files |
#4227 | ScalaGenerator should have its own list of reserved words |
#4229 | ScalaGenerator generates unneeded imports |
#4235 | JDBCDatabase calls Meta.getPrimaryKeys() for all schemas, not just for input schemas |
#4236 | Compilation error in compiled code when column is called "null" |
#4240 | JDBCDatabase fetches tables from all schemas, not just from input schemas |
#4246 | HANADataType isn't initialised in SQLDataType's static initialiser block |
#4248 | daoImplements option in MatcherStrategy not generating an implements statement in DAO class |
#4258 | Bad SQL generated for quantified row value expression predicates in Oracle |
#4262 | Manual tutorial should import java.sql.*; |
#4268 | INSERT .. VALUES clause should be rendered on a new line when rendering formatted SQL |
#4269 | No columns generated for PostgreSQL SETOF [ scalar type ] |
#4280 | Document MySQL connector's fetchSize behaviour in ResultQuery.fetchSize() |
#4286 | Manual SQL vs. jOOQ code example are not equivalent |
#4287 | Remove unused import org.jooq.Row in generated records |
#4290 | DefaultTransactionProvider should not cache Connection instance |
#4291 | Add HANA to manual documentation page about DUAL |
#4292 | Wrong emulation of "grand total" GROUP BY () clause in dialects that do not natively support them |
#4295 | Common Table Expression declarations don't set the Context.subquery() flag |
#4300 | DROP SEQUENCE IF EXISTS implemented incorrectly in Sybase SQL Anywhere |
#4306 | ArrayRecord doesn't correctly implement runtime schema mapping for Oracle |
#4308 | SQLSERVER2014 dialect doesn't generate correct LIMIT .. OFFSET clause |
#4313 | NullPointerException in code generator when bypassing GenerationTool without initialising all Lists and String[] to empty objects in Database |
#4314 | SQL Server UPDATE .. FROM illegally declares aliased tables in UPDATE clause |
#4321 | Invalid SQL generated when using nullable data types in Derby CREATE TABLE and ALTER TABLE statements |
#4324 | DROP SEQUENCE statement has a mandatory RESTRICT keyword in Derby |
#4328 | Bad implementation of ALTER TABLE .. ALTER COLUMN .. SET DATA TYPE in Derby |
#4331 | REFERENCES .. ON { DELETE | UPDATE } SET DEFAULT is currently not supported by Derby |
#4333 | Firebird CREATE TABLE regression when columns are nullable |
#4335 | Missing @Support for Firebird for CREATE TABLE statements |
#4341 | No Results are fetched from SQL Server procedures that contain update counts |
#4344 | MockStatement returns wrong update counts |
#4347 | Bad code generated for OBJECT type referencing OBJECT type from different schema |
#4348 | Missing documentation for <schemaVersionProvider/> |
#4349 | The trial / pro license is accidentally delivered with the Open Source Edition |
#4354 | Javadoc warning generated for Result.into(Field<T1>, Field<T2>, ..., Field<TN>) |
#4355 | Regression with <schemaVersionProvider/> caused by formatting of @Generated annotation |
#4358 | Wrong @Support value for SQLite which doesn't support ALTER TABLE .. DROP, SET, ADD CONSTRAINT, etc. |
#4360 | DSL.timestamp() generates wrong output in SQLite |
#4367 | Wrong implementation of MergeImpl.andNot(Field<Boolean>) and orNot(Field<Boolean>) |
#4372 | UDTRecord is not "attached" when fetched from standalone stored function call |
#4381 | No enums generated in MySQL when <forcedType/> contains <types/> matcher |
#4385 | Missing @Support annotation in MySQLDSL |
#4391 | Example exception translator should only translate SQLException |
#4399 | DSLContext.meta().getTables() returns empty fields list for table that are not in the current schema in MySQL |
#4406 | Manual refers to bad list of supported RDBMS |
#4409 | Bad syntax generated for MySQL's ALTER TABLE .. SET DEFAULT statement |
#4412 | Manual section about custom data type binding contains bad link |
#4417 | Typo in some plain SQL query part Javadocs |
#4428 | DELETE .. RETURNING is unavailable without WHERE |
#4430 | Fix routine parameter code generation for types with a binding |
#4437 | Row value expression IN predicate fails with empty rows collection |
#4440 | fetchMany() doesn't work with CUBRID |
#4447 | Empty GROUP BY () clause emulation fails in CUBRID |
#4466 | Missing CAST() in DSL.dateAdd() when the whole expression is wrapped in a cast |
#4471 | Record.getValue(Field) returns wrong value if ambiguous column names are contained in the record, and the schema name is not present in the argument |
#4481 | Missing parentheses when DSL.dateDiff(d1, d2) or timestampDiff(d1, d2) renders "d1 - d2" |
#4490 | Record not attached to Configuration yet, when RecordListener.exception() is called. |
#4494 | getSQL() method not available in CustomField.bind() as documented in the manual |
#4506 | Wrapping condition as field should produce parentheses |
#4510 | Manual typo. Local variable does not exist |
#4526 | ScalaGenerator generates broken code when using xxxImplements |
#4531 | Generated schema and generated Sequences classes import each other, which generates warnings (unused import) |
#4540 | Performance of org.jooq.impl.Fields.field(Field) could be improved heavily, if checking for identity first |
#4545 | Error generating code for Oracle Package in Oracle 10g |
#4547 | Package is not generated when an exception is thrown |
#4554 | DSLContext#batch(Query) silently discards queries |
#4557 | ExceptionTranslator in spring examples shouldn't use dialect.name() for SQLErrorCodeSQLExceptionTranslator |
#4563 | Incorrect Javadoc on DefaultRecordMapper claims that only public members / methods are considered |
#4569 | Manual refers to deprecated DefaultGenerator |
#4575 | SQL comments with javadoc terminators break generated code |
#4576 | JavaWriter uses regex syntax unsupported in Java <1.8 |
#4579 | Unnecessary log messages when a PostgreSQL database contains tables with multiple inheritance |
#4582 | Ensure that jOOQ internally uses regular expressions that are Java 6 compatible |
#4588 | NullPointerException when a TABLE OF OBJECT contains a NULL object |
#4592 | Improper Restriction of XML External Entity References ('XXE') in XMLasDOMBinding |
#4593 | Improper Resource Shutdown or Release in LoaderImpl |
#4614 | Wrong data type reported on org.jooq.Meta by dialect of a family with multiple dialects |
#4617 | NullPointerException when calling UniqueKey.getReferences() in MySQL |
Version 3.6.0 - April 22, 2015
jOOQ goes Big Data with HANA
We've been working hard to add support for our 18th database dialect: SAP HANA, which is now officially supported by the jOOQ Enterprise Edition. HANA is SAP's excellent Big Data offering, supporting column stores combined with the power of SQL standard OLAP functionality, such as window functions. Integrate HANA into your Java or Scala applications with ease, using jOOQ!
Let's talk Scala
We're glad to welcome an increasingly big jOOQ-for-Scala community, an integration where jOOQ really shines thanks to some advanced Scala language features. In order to help you integrate even better, we've now added the new ScalaGenerator that generates jOOQ meta data classes in Scala, instead of Java
Integrate your code generation with JPA
In the previous release, we've implemented a new XMLDatabase that can load arbitrary XML schema metadata formats (via XSLT). We've taken this a step further using our new jOOQ-meta-extensions artefact, which hosts alternative meta data sources, such as your JPA-annotated classes, or ERD exports.
Speaking of XML
Our XML-in-the-database integration just got better! We're showing you in a couple of example Bindings how to get the most out of your vendor-specific data types, such as XML or JSON - which can be integrated into your jOOQ queries effortlessly!
Let's talk some more DDL
This release also adds support for a couple of additional DDL statements that help you standardise your schema migrations for our 18 RDBMS. The newly supported statements are:
- ALTER TABLE ADD CONSTRAINT (with UNIQUE, PRIMARY KEY, FOREIGN KEY, CHECK)
- ALTER TABLE DROP CONSTRAINT
- CREATE TEMPORARY TABLE
SQL 2 jOOQ parser
One year ago, we've added the GUDU Software SQL 2 jOOQ parser with our deliverables. While we still believe that this is an excellent product, we have seen little demand from our users and customers - which is why we no longer ship the parser. You can still download it from GUDU Software.
MULTISET and nested records
While we have published (as promised) some API for nested record support, we're not quite convinced of its design yet. This is why this API is still marked as "experimental". Stay tuned for future releases when we'll take these advanced ORDBMS features one step further.
Tons of new convenience API and bugfixes
jOOQ wouldn't be jOOQ if it wasn't for the myriad convenience methods that make your SQL integration lives so much easier. We've listened to our users and customers and added another bulk of useful fetch(), execute(), map() and many other convenience methods that make your SQL integration fun and efficient.
API Diff:
See what's changed in terms of an API diff here: https://www.jooq.org/api-diff/3.5-3.6
Features and improvements
#231 | Add BlobBinding and ClobBinding to use java.sql.Blob and java.sql.Clob on a JDBC level |
#584 | Add a XMLasDOMBinding that can be used to bind SQLXML data types to org.w3c.dom.Node |
#1363 | Generate a copy constructor for POJOs |
#1391 | Add support for the Postgres "every" aggregate function |
#1464 | Allow for a plugin architecture in jooq-meta, jooq-codegen, for custom schema-sources and generation-targets |
#2221 | The manual's section about "Reusing a Query's PreparedStatement" does not mention what the behaviour is, when the underlying Connection is closed |
#2498 | Add support for SQL Standard PERCENTILE_CONT() and PERCENTILE_DISC() inverse distribution functions |
#2626 | Add org.jooq.SQL as a plain SQL type (for templating) |
#2639 | Add stored procedure OUT values to DEBUG log output |
#2664 | Add flag to Loader API to enable batch execution |
#2686 | Add Result.fetchParents(ForeignKey) and Result.fetchChildren(ForeignKey) to fetch relations in a single query |
#2899 | Support generating code based on JPA annotations |
#2905 | Add support for named parameters in BatchBindStep.bind() |
#2919 | Distinguish various PostgreSQL versions in the PostgreSQL family: 9.3, 9.4 |
#2936 | Move .settings, and other Eclipse-related artefacts in a separate place |
#3052 | Add a section to the manual explaining table-valued functions |
#3188 | Add support for LEAD() / LAG() with Row[N] arguments |
#3329 | Support the SQL standard array_agg function |
#3336 | Add code generation flag to enable / disable imports in generated code |
#3338 | Add support for ALTER TABLE ADD CONSTRAINT .. UNIQUE, PRIMARY KEY statements |
#3376 | Add support for PostgreSQL SETOF functions |
#3614 | DefaultRecordMapper only sets declared fields of the target type, no inherited fields |
#3620 | Add section to the manual explaining how to use jOOQ with Nashorn |
#3643 | Ensure that JPA annotations on private members are considered correctly |
#3649 | Support DELETE FROM ... RETURNING |
#3706 | Add a paragraph to the manual explaining how to manually unmarshal code generation Configuration via JAXB |
#3708 | Emit a newline character when performing formatted logging |
#3712 | Add Oracle Spatial examples |
#3717 | Use try-with-resources in manual and tutorial |
#3734 | Implement "$0" as a default expression in matcher strategy rules |
#3744 | Add more precise subtypes for InvalidResultException |
#3748 | Add public Routine T getValue(Parameter<T>) and setValue(Parameter, T) methods |
#3765 | Add support for HANA |
#3781 | Add support for DSL.trunc(date, DatePart) for H2 |
#3784 | Add additional <global[XXX]References/> flags to prevent generation of individual reference classes |
#3797 | For table-valued functions, generate also a static method in Tables.java |
#3800 | jOOQ-Meta should log formatted queries on exception |
#3801 | Add Result#intoMap and Result#intoGroups variants that take field index or field name |
#3808 | Improve manual's section about batching by making it clear that bind() binds records, not individual values |
#3810 | Add fetchOne(RecordMapper) shortcut method to ResultQuery |
#3816 | Use char literals instead of single-character String constants where applicable |
#3819 | Add Constants.XSD_META and Constants.NS_META to describe the new jooq-meta-x.x.xsd |
#3830 | Add support for XSL transformation to XMLDatabase |
#3840 | Add a JavaEE example project with EJB and JSF |
#3842 | Add DSL.field(Name), DSL.table(Name), DSL.schema(Name), DSL.sequence(Name) methods |
#3843 | Deprecate DSL.fieldByName(), DSL.tableByName(), DSL.schemaByName(), DSL.sequenceByName() |
#3844 | Add a new SQLDialect.DEFAULT instead of SQL99 |
#3846 | Let examples work with latest release, not with SNAPSHOTs |
#3847 | Document the fact that Collection<? extends Condition> or Condition[] arguments are always and-connected |
#3848 | Add DSL.dateSub() as a convenience for adding negative dates via DATE_ADD() |
#3849 | Add PostgresDSL.stringToArray(X, Y, Z) support |
#3851 | Add a @PlainSQL annotation to all methods that produce plain SQL objects |
#3853 | Add support for CREATE TEMPORARY TABLE and all related flags |
#3854 | Deprecate DSL.queryPart() in favour of DSL.sql() |
#3865 | Add an example project showing how to use jOOQ with JavaFX |
#3870 | Add support for aggregate FILTER clause |
#3871 | Add support for PostgreSQL 9.4 |
#3872 | Emulate MEDIAN(x) via PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY x) in PostgreSQL 9.4 |
#3873 | Add SQLDialect.predecessor() to establish historic dependencies between SQLDialects |
#3874 | Add a AbstractXMLasObjectBinding that can be used to bind SQLXML data types to JAXB-annotated types |
#3875 | Add support for PostgreSQL 9.4 ordered-set aggregate functions |
#3876 | Add support for SQL Server 2014 |
#3878 | Add R[] ResultQuery.fetchArray() |
#3879 | Rename Result.intoArray() into Result.intoArrays() |
#3882 | Overload JavaGenerator.generateXXX() methods to contain a JavaWriter argument |
#3886 | Add Field<Record[N]> DSL.field(Row[N]) to allow for nesting rows in SELECT clauses |
#3889 | Add DataType.getBinding() |
#3891 | Cache Record Constructor in CursorImpl |
#3894 | Clarify Record.getValue() behaviour in Javadoc |
#3897 | Add support for nested "to-one" POJOs in DefaultRecordMapper |
#3900 | Implement better formatting for nested Records |
#3904 | Add DSL.and(Condition...) / DSL.or(Condition...) |
#3907 | Upgrade Spring version in tutorials / manuals |
#3915 | Calls to Configuration.derive() create a Configuration that indirectly references the previous Configuration instance |
#3928 | Add support for ORA_ROWSCN, SCN_TO_TIMESTAMP() to OracleDSL |
#3931 | Add RenderKeywordStyle.AS_IS |
#3934 | Add StopWatch.split() to get current time |
#3941 | Add additional DSL.param() methods to create unnamed bind value placeholders |
#3956 | Add Configuration set(DataSource) and set(Connection) for convenience |
#3961 | Apply Base64 encoding to binary types when formatting them to XML, JSON, etc. |
#3975 | Add support for bulk insertion in the Loader API |
#3981 | Implement Meta.getTables()[x].getPrimaryKey().getReferences() |
#3983 | Add <T> List DSLContext.fetchValues(TableField) |
#3984 | Implement Meta.getTables()[x].getReferences() |
#3985 | Add support for more PostgreSQL array functions |
#3986 | Add DSL.choose() as a synonym for DSL.decode(), and DSL.when(Field), DSL.when(Condition) as shortcuts |
#3992 | Add <T> DSL.coalesce(Field, T) |
#4004 | Make the manual's version bar at the top a coloured bar |
#4009 | Add <R extends Record> Table DSL.table(R...) |
#4012 | Add new LoaderConfigurationException to indicate bad configurations in Loader API |
#4013 | Add int Loader.executed(), a new counter that counts the number of executed statements |
#4019 | Add system property to remove the logo from the log output |
#4021 | Add a ScalaGenerator |
#4027 | Let INSERT statements default to using DEFAULT VALUES when no values are specified |
#4044 | Add support for ALTER TABLE DROP CONSTRAINT statements |
#4045 | Add AlterTableStep.addColumn() and dropColumn() methods as synonyms for add() and drop() |
#4046 | Add support for ALTER TABLE ADD CONSTRAINT .. FOREIGN KEY statements |
#4047 | Add DSL.deleteFrom() alias for DSL.delete() |
#4048 | Add support for ALTER TABLE ADD CONSTRAINT .. CHECK statements |
#4058 | Mention SimpleFlatMapper from the jOOQ manual |
#4063 | Add DSLContext.truncate(String) convenience method |
#4064 | Add PostgreSQL support for DSLContext.lastId() |
#4071 | Emit a warning when a batch statement doesn't receive the right number of bind values |
#4085 | Add DSL.list(QueryPart...) to allow for creating lists in SQL templates |
#4086 | Add a manual section about Record.into(Table<?>) |
#4097 | Use SQL standard EXTRACT() function also in Oracle |
#4099 | Document how to use Converter and Binding without the code generator |
#4105 | Add an optional, synthetic COLUMNS clause to the INSERT API for convenience |
#4107 | Add Routine.getReturnParameter() |
#4108 | Add ExecuteListener.outStart(ExecuteContext) and outEnd(ExecuteContext) to capture fetching of Routine OUT parameters |
#4110 | Overload DDL API to accept Name instead of String arguments |
#4122 | Log code generation configuration XML only in DEBUG level |
#4125 | Add MockConnectionProvider and MockConfiguration for convenience |
#4126 | Add void DSLContext.mock(MockDataProvider, MockRunnable) and <T> T mockResult(MockDataProvider, MockCallable) |
#4127 | Upgrade embedded jOOR dependency to 0.9.5 |
#4129 | Add support for @javax.persistence.Id |
#4140 | Recognize SQLDroid JDBC URLs in JDBCUtils.dialect(String) |
#4141 | Add support for specifying the encoding when loading CSV or JSON with the Loader API |
#4143 | Add onRow(LoaderRowListener) to the Loader API |
#4144 | Explain the rationale of the transaction examples in the manual |
#4146 | Generate PL/SQL constants |
#4152 | Add <T> Field TableLike.field( { String | int }, { Class, DataType, Field } ) |
#4154 | Link to source code from https://www.jooq.org/java-8-and-sql |
#4174 | Split the manual's section about the INSERT statement in several sections |
#4179 | Add support for MySQL's mandatory ON clause in the DROP INDEX statement |
#4198 | Improve manual section about SQL injection |
#4206 | Add Converter<T, T> Converters.identity(Class) to produce an identity converter |
#4207 | Upgrade Spring Boot version in example to 1.2.3. |
#4215 | Remove Gudu Software's SQL 2 jOOQ Parser from deliverable |
#4216 | Remove obsolete "release" profile from pom.xml files |
#4219 | Implement an instance toString() method on JSONObject |
API changes (backwards-compatible)
API changes (backwards-incompatible)
#3855 | Oracle REAL and FLOAT types cause code generator to produce BigInteger instead of Double types |
#3885 | Add a SelectField marker interface that allows for alternative column expressions in the SELECT clause |
#4106 | Add support for T-SQL optional INTEGER return values from stored procedures |
#4196 | UpdateResultStep is erroneously declared as a subtype of Insert |
Behavioural changes (backwards-incompatible)
#3860 | Allow to specify defaults for all regular expression flags in the code generation configuration. Add CASE_INSENSITIVE to defaults |
#3982 | Empty, OR-connected CombinedConditions should return FALSE, not TRUE |
#4161 | { INSERT | UPDATE | MERGE } .. SET [ Record ] doesn't take changed flags into account |
Bug fixes
#2522 | Codegen Schema mapping doesn't work for UDT |
#2647 | Code generation error when Postgres stored function contains several parameters with the same name |
#3170 | Improve manual's jOOQ examples by always using fetch() or execute() where applicable |
#3255 | DataTypeException: Cannot convert from "" (class java.lang.String) to class [B when casting to MySQL BINARY types |
#3341 | Cannot use ALTER TABLE ADD or CHANGE statements on MySQL for all column data types |
#3378 | Error when fully qualifying PostgreSQL table-valued functions in SELECT clauses |
#3417 | Add documentation about DEFAULT and DEFAULT VALUES to INSERT and UPDATE manual pages |
#3727 | Invalid SQL generated when window definitions from WINDOW clause contain frame clauses |
#3745 | NullPointerException when <jdbc/> is not provided and isn't provided either |
#3778 | PostgreSQL enum array types have to be cast with their fully qualified name |
#3803 | CREATE TABLE statement does not generate NOT NULL constraint |
#3809 | Fix typo in Javadoc in ResultQuery |
#3811 | Potential NullPointerException in Cursor.fetchOne(RecordMapper) and other methods |
#3817 | When used with set operations, ORDER BY must not contain any qualified fields |
#3822 | Invalid SQL for Postgres created with values(Row1...) |
#3824 | PostgreSQL dateAdd() erroneously returns a TIMESTAMP value |
#3831 | <dateAsTimestamp/> deprecation warning is displayed even if the flag is not active |
#3833 | org.jooq.CreateTableAsStep.column(Field<T> field, DataType type) SQLite |
#3835 | SQLite's CREATE VIEW statement doesn't allow to rename columns |
#3838 | Bad @Support annotations on ALTER TABLE statements, which are not supported by SQLite |
#3845 | NullPointerException in code generator when there is an empty <inputSchema/> element in Oracle |
#3850 | Broken link towards 3.5 documentation in 2.6 documentation |
#3861 | Minor manual typo |
#3863 | CSV-Export with delimiter only does not work properly |
#3877 | Generated "fetchBy[ColumnName]" methods in DAOs shouldn't Mode.POJO |
#3880 | Cannot access private JavaGenerator.newJavaWriter() method |
#3888 | Data type conversion fails when using a Binding<byte[], Serializable> and passing a byte[] as user input |
#3899 | Compilation error in generated code when a sequence name ends with $ |
#3905 | LoggerListener and StopWatchListener should be placed after user listeners |
#3909 | Inefficient number to number conversion in org.jooq.tools.Convert |
#3911 | DefaultRecordMapper ignores @ConstructorProperties for property names that don't have a matching getter |
#3919 | Bad caching of JPA-annotated getters leads to wrong mapping into POJOs that have @ConstructorProperties |
#3932 | jooq-runtime-3.5.0.xsd declares wrong namespace |
#3936 | AbstractQuery unnecessarily creates two DefaultRenderContext instances. |
#3940 | Batch statements do not work when queries contain inlined bind variables |
#3944 | AbstractScope creates an excessive amount of HashMaps, internally |
#3946 | Replace ArrayList<ExecuteListener> by ExecuteListener[] in ExecuteListeners to avoid excessive Iterator creation |
#3947 | Avoid creating unnecessary Iterators and ArrayLists in AbstractStore.getAttachables() |
#3954 | Avoid wrapping Field[] in a new RowImpl every time a Record is created |
#3957 | java.lang.NoSuchMethodException: createARRAY when using Oracle arrays with BoneCP |
#3962 | The H2 emulation of SHR might produce rounding errors |
#3966 | Inefficient BIT_COUNT() function for those dialects that do not natively support SHR() |
#3977 | Meta.getTables() also returns entries for indexes for PostgreSQL |
#3987 | The manual refers to a non-existing DSLContent.decode() function, which is really contained in DSL |
#3988 | Incorrect IntelliJ directory listings in .gitignore |
#3993 | ResultQuery.fetchAny() methods Javadoc erroneously claims throwing of InvalidResultException |
#3998 | Cache internal BindingGetResultSetContext instance across a single Cursor |
#4000 | Avoid {ResultSet | CallableStatement | SQLInput).wasNull() calls if not necessary, as they're somewhat expensive on some JDBC drivers |
#4010 | Confusing wording in manual section about org.jooq.Binding |
#4011 | Loader does not call release() when acquiring connections to commit transactions |
#4017 | jooq-meta-3.5.0.xsd is not valid XSD 1.0 |
#4022 | NullPointerException when generating SQLite table with composite primary key |
#4026 | Add a "USE library" command to the manual's tutorial |
#4028 | Loader API's "onDuplicateKeyIgnore()" executes inefficient SELECT |
#4036 | Obsolete remark in RecordListener Javadoc about batch semantics |
#4041 | Bad unnesting of UDT arrays in PostgreSQL |
#4052 | NullPointerException when generating source code for PostgreSQL table-valued function that returns nested arrays |
#4056 | Query.bind(String, Object) binds only to the first occurrence of a named bind value |
#4065 | Exception when loading array results from plain SQL queries into a Record |
#4075 | Bad result from Query.getBindValues() when named Params are repeated |
#4079 | Boolean datatype not handled with MySQL dialect |
#4091 | ORA-01461: can bind a LONG value only for insert into a LONG column, RC=5100 |
#4093 | Typo in Javadoc on DataType.asConvertedDataType() |
#4096 | jooq-meta-3.5.2.xsd doesn't specify the right namespaces |
#4100 | Use "<" for "<" and ">" for ">" in javadoc |
#4101 | Wrong DSL.currentTimestamp() and currentTime() implementations in Oracle |
#4114 | Compilation error when a stored procedure has a parameter named "value" and the generator strategy generates lower case literals |
#4117 | Invalid SQL generated when using UNSIGNED data types with MySQL DDL statements |
#4120 | Invalid SQL generated when using TINYTEXT with MySQL DDL statements |
#4121 | Row value expression IN predicates with subqueries are not formatted correctly |
#4128 | @javax.persistence.Column.name() is case-insensitive |
#4132 | GeneratorStrategy.instanceFields should be true by default |
#4134 | No milliseconds value when reading Timestamp values from SQLite |
#4147 | SQLDialectNotSupportedException: ARRAY TABLE is not supported for SQL99 |
#4151 | FOR UPDATE .. OF doesn't allow qualified column names |
#4156 | Cannot fetch REF CURSOR OUT parameters from Oracle stored procedures when using SQLDialect.ORACLE11G |
#4157 | Package procedures without arguments are not generated in Oracle 12c |
#4160 | SQL generated by DSL.dateAdd() is invalid for certain dates in Oracle |
#4170 | Schema name rendered twice when calling static member procedure in Oracle |
#4173 | NullPointerException when using SQL99 dialect with XMLDatabase for code generation |
#4176 | Wrong @Support value for SQLite which doesn't support DEFAULT in INSERT or UPDATE statements |
#4182 | ArrayIndexOutOfBoundsException in org.jooq.impl.Utils.renderAndBind |
#4185 | ExecuteType.BATCH JavaDoc: not yet supported |
#4187 | SQLite timestamps with trailing fractional zeros are misinterpreted |
#4190 | Generated Record.values() does nothing |
#4193 | Wrong H2 routines generated since recent H2 version |
#4197 | Incomplete Javadoc and @Support annotation on UPDATE .. RETURNING with respect to DB2 emulation |
#4204 | Broken JavaFX example |
Version 3.5.0 - November 21, 2014
The new Binding SPI
The main improvement of this exciting release is the new org.jooq.Binding SPI which can be used to fully control all aspects of a user-type's JDBC interaction. This goes much further than the existing org.jooq.Converter SPI that can be used to map standard JDBC types to user-types. With the new Binding SPI, virtually *ALL* vendor-specific types can be supported now. Examples include PostgreSQL's JSON or HSTORE types, or Oracle's DATE type - which is really incorrectly represented via java.sql.Timestamp, which is why we have retrofitted the existing <dateAsTimestamp/> feature to use such bindings, now.
Stored procedures are everywhere
Stored procedure support was generally improved in this release. This includes lots of new little features and conveniences for use with PL/SQL or Transact-SQL. For instance, jOOQ 3.5.0 now supports cross-schema references of PL/SQL OBJECT and TABLE types, which allows for binding directly to Oracle Spatial. We've blogged about this exciting improvement here: https://blog.jooq.org/painless-access-from-java-to-plsql-procedures-with-jooq/
And while we were at it, we've also added basic support for Oracle AQ, which integrates very nicely with our OBJECT type support!
In Transact-SQL and MySQL, we now support fetching arbitrary numbers of Results from stored procedures, and we've also implemented support for Firebird PSQL, including Firebird's very interesting syntax for table-valued functions.
By the way, we support user-defined aggregate functions for a variety of databases, including Oracle, PostgreSQL, and HSQLDB. Definitely something you should look into!
SQL improvements
In this release, we've finally got support for UNION, INTERSECT, and EXCEPT right with respect to nesting such operations, as well as combining them with ORDER BY and LIMIT .. OFFSET.
Let's talk some more DDL
We've continued to add support for DDL statements, including
- CREATE TABLE
- CREATE TABLE AS SELECT
- CREATE VIEW and DROP VIEW
- CREATE INDEX and DROP INDEX
- CREATE SEQUENCE and DROP SEQUENCE
- DROP .. IF EXISTS
We'll continue to add support for more DDL statements also in the future.
Code generation improvements
We've added support for the new XMLDatabase, a code generation configuration that allows to read meta information from XML formats, e.g. from a standard INFORMATION_SCHEMA.xml, or from an ERD's XML export format: https://blog.jooq.org/importing-your-erd-export-into-jooq/
Future versions of jOOQ will include built-in support for a variety of XML formats.
We've had an awesome contribution by Etienne Studer from Gradleware to help our users integrate the jOOQ code generation with their Gradle builds.
Last but not least: Informix!
Oh, and by the way, we now also support IBM's second most popular database: Informix. Support for this database will be included in the jOOQ Enterprise Edition.
API Diff:
See what's changed in terms of an API diff here: https://www.jooq.org/api-diff/3.4-3.5
Features and improvements
#561 | Add support for the Informix database |
#994 | Add support for the Postgres "hstore" data type |
#1341 | Add DSL.using(String url) and other methods that mimick DriverManager.getConnection() |
#1380 | Generate equals(), hashCode() on POJOs |
#1392 | Add formatInsert() to render insert statements from a Result |
#1410 | Add support for the Postgres "DISTINCT ON" clause |
#1658 | Add support for SQL standard UNION syntax. jOOQ's current understanding of UNION is just convenience |
#1761 | Reference manual versions between each other |
#2054 | Implement quantified comparison predicates for Row[N] row value expressions |
#2155 | Add Converter support to Routines and UDTs |
#2209 | Add <T1, T2, .., T[N]> Result<Record[N]<T1, T2, .., T[N]>> Result.into(Field<T1>, Field<T2>, .., Field<T[N]>) in order to transform Results / Records into another type |
#2289 | Add jOOQ-flyway-example, a documentation module to show how to integrate with Flyway |
#2604 | Add section to the manual explaining how asynchronous querying can be achieved |
#2674 | Add support for stored procedures in MockConnection / MockDataProvider / MockExecuteContext |
#2788 | Add support for the PostgreSQL "json" data type |
#2886 | jooq-codegen-maven should look into project dependencies for jdbc driver |
#2907 | Emulate UPDATE .. RETURNING through SELECT FROM FINAL TABLE (UPDATE ...) in DB2 |
#2925 | Add support for Firebird stored procedures |
#3121 | Skip code re-generation when schema is known to be the same |
#3151 | Add "question mark" with tool-tip to the manual to allow for jumping to the "how to read this manual" section |
#3248 | Add support for Binding (i.e. "Type Providers") |
#3337 | Add support for the CREATE TABLE statement |
#3339 | Add support for CREATE INDEX and DROP INDEX statements |
#3340 | Add support for CREATE VIEW and DROP VIEW statements |
#3346 | Allow for omitting the JDBC driver property in the code generator |
#3355 | Add support for CREATE SEQUENCE and DROP SEQUENCE statements |
#3370 | Allow for overriding the class Javadocs for generated objects |
#3375 | Add support for PostgreSQL table-valued functions |
#3381 | Add support for CREATE TABLE AS statements |
#3386 | Add some test cases using Java 8 Streams for functional-relational transformation |
#3388 | Replace SQL Server's ROW_NUMBER() OVER(ORDER BY @@version) by ORDER BY (SELECT 0) |
#3389 | Add DSLContext.currval(String) and nextval(String) for convenience |
#3412 | Add List DSLContext.fetchValues(...) similar to the existing fetchValue(...) methods |
#3418 | Add DSL.defaultValue(Field<T>) for convenience |
#3425 | Add support for Oracle AQ |
#3431 | Add support for MySQL index hints |
#3435 | Add support for SQL Server's SELECT .. INTO [new table] syntax |
#3442 | Implement MockResultSet.getArray() methods |
#3443 | Add support for conversion of values / arrays to the JDBC Array type in Convert |
#3444 | Add MockArray, a mock implementation of JDBC's Array type |
#3451 | Add XMLDatabase to generate a database schema from an XML file |
#3477 | Add Field.as(Field) to rename a field to another field's name |
#3480 | Add XXXContext.dialect() and XXXContext.family() for convenience |
#3483 | Let <forcedType/>'s <expression/> match both fully qualified column names as well as unqualified column names |
#3495 | Add an example project showing how to use jOOQ's code generator with Gradle |
#3496 | Log a DEBUG message when a Query is executed which returns Query.isExecutable() == false |
#3501 | Add ResultQuery.fetchSet() and Result.intoSet() methods to return LinkedHashSets |
#3506 | Instrument the jOOQ API during integration tests to verify correct application of @Support annotations |
#3511 | Improve DISTINCT predicate emulation through INTERSECT |
#3512 | Add DSL.count(Table<?>) and DSL.countDistinct(Table<?>) to support the PostgreSQL-specific COUNT() extension |
#3513 | Streaming version of formatCSV/formatXML |
#3519 | Document the PostgreSQL JDBC's limitations with respect to large cursors when using Connection.autoCommit = true |
#3525 | Implement more verbose DEBUG logging for jOOQ-meta's include / exclude mechanism |
#3532 | Add support for DROP ... IF EXISTS clauses in DDL |
#3551 | Copy plain SQL query construction API to DSL from DSLContext |
#3557 | Add support for PostgreSQL user-defined aggregate functions |
#3558 | Add Setting to enable / disable fetching of warnings |
#3559 | Propagate jOOQ-codegen's relations flag also to jOOQ-meta, to prevent (possibly expensive) queries to fetch relations |
#3565 | Add XXXContext.settings() for convenience |
#3566 | Add GenerationTool.generate(String) to generate code from an XML string |
#3569 | The <database/> tag is no longer mandatory in the code generator configuration |
#3579 | Emulate nested set operators in databases that don't support them natively |
#3592 | Add Setting to enable Oracle scalar subquery caching for stored function calls |
#3595 | Add MockResult<init>(Record data) convenience constructor |
#3596 | Let code generator empty generated packages on a per-schema basis |
#3597 | Generate table and column comments also for PostgreSQL |
#3598 | If tables define their own comments, don't generate "This class is generated by jOOQ." in Javadocs |
#3599 | Implement nicer formatting of @Generated annotation |
#3600 | Add support for SQL standard SELECT .. WITH CHECK OPTION |
#3610 | Explain the differences between keeping generated sources under version control or not |
#3611 | Add a jOOQ / Nashorn example to the repository |
#3612 | Add an example project showing how to import an ERD export format to the code generator |
#3622 | Add support for Field.in(Result<Record1<T>>) and Row[N].in(Result<RecordN<T1, ..., TN>>) |
#3623 | Add ParamType.NAMED_OR_INLINED to render named parameters only if a name is given |
#3626 | Add Map<S, Result<R>> Result.intoGroups(Table<S>) |
#3627 | Add simplified API for CASE WHEN [ condition ] THEN [ select ] expressions |
#3628 | Add <T> Field<T> DSL.field(Select<? extends Record1<T>>) |
#3633 | Add a section to the manual about jOOQ and NoSQL |
#3638 | Let ResultQuery<R> extend Iterable<R> |
#3644 | Enhance DSL API to work around Nashorn interoperability issue with overloading and varargs |
#3661 | Log some info about the type being matched by a <forcedType/> configuration |
#3667 | <types/> configuration doesn't work for Derby DATE types |
#3668 | Let GenerationTool also search absolute and relative paths |
#3669 | Make the code generator's <database/> element optional |
#3670 | Add DSL.coerce(Object, ...<T>) for convenience |
#3671 | Add alternative DSL.concat() syntax for convenience |
#3672 | Add OracleDSL.toNumber() |
#3677 | Add a paragraph to the manual indicating that the manual is licensed CC-BY-SA 4.0 |
#3678 | Add some JavaBeans-style setters to the DefaultConfiguration to simplify configuration via Spring |
#3680 | Remove all unit tests that make assumptions on how exactly the SQL is rendered |
#3681 | Fetch all result sets from executed stored procedures |
#3688 | Remove the confusing CO_AUTHOR_ID column from the manual |
#3690 | Add a manual page header indicating that a version has gone "end of life" |
#3702 | Add Configuration.family() for convenience and API consistency |
#3740 | Add Table.newRecord() and UDT.newRecord() to construct new records with DefaultConfiguration |
#3746 | Add DSLContext.fetchExists(Select<?>) |
#3752 | Make <jdbc/> element optional in code generation configuration |
#3754 | Explain primitive type conversion in Convert.convert() Javadoc |
#3756 | Regenerate files only if there is a difference |
#3760 | Add Record.intoList() |
#3769 | Add org.jooq.Converters, a chained Converter implementation |
#3773 | Explain jOOQ's understanding of Configuration thread safety in the Configuration Javadoc |
#3775 | Let QueryPart.toString() generate formatted SQL |
#3782 | Add a method to create a org.jooq.util.Database by SQLDialect |
API changes (backwards-compatible)
#3345 | Deprecate org.jooq.api.annotation.State and Transition annotations |
#3356 | Deprecate Select.fetchCount() |
#3703 | Deprecate CastMode.SOME and RenderContext.cast() |
#3770 | Deprecate <dateAsTimestamp/> |
API changes (backwards-incompatible)
Behavioural changes (backwards-incompatible)
#2486 | Allow to specify precision, scale, length for type-rewrites in <forcedType/> |
#3000 | Add Setting to enable MySQL backslash escaping |
#3407 | DDL statements accepting String names should generate quoted names, not plain SQL |
#3541 | Change DSLContext.nextval(String) and currval(String) to internally call DSL.sequenceByName() instead of DSL.sequence() |
Bug fixes
#2080 | Syntax error in rendered SQL when using limit().offset() with aliased projections in SQL Server |
#3206 | DSL.field(Condition) doesn't correctly handle NULLs when emulating boolean fields with a CASE expression |
#3347 | Field.in(T...) should defend against Collection arguments |
#3353 | Manual Javadoc anchors are no longer correct with the recent changes of JDK 8 Javadocs |
#3359 | store() after copy() executes an UPDATE instead of an INSERT, when Settings.updatablePrimaryKeys is set |
#3360 | SQLite regression when using special characters in identifiers |
#3362 | DSLContext.batchStore() executes INSERT if records are batch stores are executed two times in a row on new records, if Settings.updatablePrimaryKeys is set to true |
#3363 | UpdatableRecord.store() executes UPDATE instead of INSERT after delete(), if Settings.updatablePrimaryKeys is set to true |
#3369 | Render CAST(? AS DATE) for java.sql.Timestamp bind values that are bound to Oracle DATE columns |
#3372 | The syntheticPrimaryKeys code generation option is currently undocumented |
#3373 | The manual's page about the DUAL table does not list all the supported databases |
#3382 | NOT NULL constraints and type information are incorrectly generated when using Firebird DOMAINs for data types |
#3390 | Add missing documentation about the new jOOQ 3.4 transaction API |
#3392 | Call setAccessible(true) only if really needed |
#3400 | ALTER TABLE generates invalid syntax on Firebird when data types are nullable |
#3402 | Wrong character length generated by jOOQ for Firebird |
#3408 | Remove the default log4j.xml configuration file from the maven plugin again |
#3413 | Oracle generated ArrayRecords cannot be constructed through reflection if deprecated flag is set to off |
#3420 | NullPointerException when generating code for Oracle AQ Tables |
#3427 | Internal QueryCollectorSignal exception escapes into user code when not dealt with in ExecuteListener |
#3430 | JDBC escape syntax is not correctly rendered from plain SQL when plain SQL contains newlines |
#3436 | Manual sections about transactions documents ctx to be a DSLContext instead of Configuration |
#3437 | QualifiedField does not respect RenderContext.qualify() |
#3445 | Cannot run Maven code generator with professional edition |
#3450 | Backslashes in SQL comments don't get escaped |
#3455 | UPDATE .. FROM statement renders incorrect SQL for derived tables or aliased tables |
#3456 | Name clash in generated code when Routine argument is called "f" (functions) or "p" (procedures) |
#3462 | Field<Object>.in(Object...) can be called with Select<?> arguments, accidentally |
#3463 | Field.in(...) methods shouldn't return trueCondition() or falseCondition() |
#3473 | java.lang.IllegalArgumentException: Field (null) is not contained in Row |
#3488 | Compilation error in generated code, when a similar tables T_A and TA exist |
#3489 | DefaultTransactionProvider does not call Connection.releaseSavepoint(Savepoint) after commit |
#3507 | Bad @Support annotation on Select.intersect() and Select.except() |
#3514 | ResultQuery.fetchLazy() ignores fetchSize() |
#3520 | Duplicate column information in foreign key references for foreign keys that share the same name in different tables |
#3526 | Unnecessary warning logs introduced in code generation |
#3533 | Avoid using named parameters for Oracle, if not really needed |
#3537 | Incorrect call to releaseSavepoint() |
#3542 | Oracle DDL statements do not allow for using bind variables |
#3544 | Add a DDLQuery marker interface, which all DDL Query types should extend |
#3545 | Error when using qualified, case-sensitive sequence names in H2 |
#3547 | DSLContext.batch(String) doesn't accept bind variables |
#3552 | Oracle Stored procedures using type synonyms in signatures cannot be used through jOOQ |
#3556 | Generated Oracle Stored procedures do not reference types from other schemas |
#3560 | Slow discovery of primary keys in very large MySQL databases |
#3567 | Code generator error message refers to wrong XSD |
#3577 | Don't render "empty" OFFSET 0 clauses |
#3578 | Slight manual bug referring to inexistent ExecuteContext.dialect() method |
#3582 | Record.from(Object) does not consider DataType.nullable() which may lead to constraint violations when inserting |
#3586 | Context.paramType() is initially null instead of INDEXED |
#3590 | Manual erroneously claims that the SQL standard allows SELECT without FROM |
#3591 | Compilation error generated in manual's tutorial code |
#3602 | Cannot INSERT into view |
#3608 | Typo in documentation of transaction method |
#3624 | Compilation errors when Converters are applied to generated Routines and UDTs |
#3630 | ArrayOutOfBoundsException when using backslash escaping in MySQL with jOOQ plain SQL |
#3634 | Record.into(Table) maps to the wrong table when passing an aliased table after a self-join |
#3639 | java.lang.NoSuchMethodException: createARRAY when using Oracle arrays with Spring TransactionAwareDataSourceProxy |
#3648 | Use JDBC Escape syntax for MySQL Date / Time literals to circumvent a known MySQL bug |
#3650 | NullPointerException on TableRecord.insert() when primary key information is not present |
#3664 | UNION ALL, ORDER BY, and LIMIT regression |
#3665 | Typos in Javadocs |
#3673 | OracleDSL.toChar() methods shouldn't require String types |
#3682 | PostgreSQL INSERT .. RETURNING doesn't work with plain SQL table |
#3696 | OutOfMemoryError with SQL Azure, caused by long-running loop of consuming further exceptions |
#3705 | The jOOQ "flash log" doesn't display nicely when using java.util.logging |
#3711 | Incorrect code generated for cross-schema OBJECT type references |
#3718 | Exceptions on rollback hide the original exceptions causing the rollback |
#3723 | Add org.jooq.Scope to unify all Configuration, Settings, and data map access in a single API |
#3730 | Cannot use regex COMMENTS in <forcedType/>'s <expression/> |
#3732 | Improve performance of <forcedType/> regex evaluation |
#3733 | Code generator should use CHAR_LENGTH columns for Oracle, instead of DATA_LENGTH |
#3741 | MySQL ResultSet streaming conflicts with internal SHOW WARNINGS call |
#3758 | ExecuteListener.warning() is not listed as a method in the Javadoc |
#3762 | Bad emulation of DUAL table in HSQLDB when connecting with a DBA user on a database with more than one user |
#3792 | Code generator erroneously refers to "singleton instances" of tables in generated Javadoc |
Version 3.4.0 - June 20, 2014
With this awesome new minor release version, we have finally started supporting a couple of very important aspects of the SQL language:
- Common table expressions
- Transactions
- DDL
Common table expressions have been missing from jOOQ for a long time, and they're now finally part of our DSL API, both for recursive or regular usage.
Transactions are handled very nicely in JavaEE or through Spring TX. But if you're running small standalone programs with JDBC (and jOOQ) only, you have to resort to a transaction API that is no longer contemporay. With jOOQ 3.4, we're now shipping a Java-8 ready transaction API and a default implementation backed by JDBC transactions. Our manual also contains an example implementation that is backed by Spring TX. While we do not want to compete with popular transaction models, we do want to provide a simple, functional-interface oriented API to apply transactions in client code.
DDL is very hard to standardise across databases, and with jOOQ 3.4, we have now started adding type safe support for some DDL statements, including thus far:
- ALTER SEQUENCE
- ALTER TABLE
We're going to be adding support for more DDL statements in jOOQ 3.5 as part of our more general DDL support strategy.
Apart from that, there is a tremendous amount of minor improvements. See below for details:
API Diff:
See what's changed in terms of an API diff here: https://www.jooq.org/api-diff/3.3-3.4
Features and improvements
#454 | Add support for CTE (Common Table Expressions / WITH-clause) |
#682 | Mavenise jooq-test |
#883 | Add support for DDL statements |
#1061 | Support "DEFAULT" keyword in INSERT and UPDATE statements |
#2573 | Generate DAOs for tables with composite primary keys |
#2646 | SQL Server error "The text, ntext, and image data types cannot be compared or sorted" when using LIMIT with a SELECT [text, image] statement |
#2675 | Add test to verify if jOOQ correctly binds NULL values with the right JDBC type in batch INSERT operations |
#2694 | Unify RenderContext and BindContext traversal |
#3010 | Generate POJOs for Oracle and PostgreSQL UDTs |
#3016 | Adapt manual to recommend also other popular connection pools |
#3030 | Add support for ALTER SEQUENCE ... RESTART [ WITH ... ] |
#3075 | Add support for Oracle TEMPORARY tables |
#3076 | Add ExecuteListener.warning(ExecuteContext) to allow for listening to SQLWarnings |
#3077 | Let Sequence implement QueryPart |
#3080 | Generate Interfaces for Oracle and PostgreSQL UDTs |
#3081 | Let generated POJOs reference generated UDT POJOs instead of UDT Records |
#3084 | SQL Server unique indexes are not loaded by jOOQ-meta |
#3093 | Add code-generation configuration to treat UNIQUE keys as primary keys to generate UpdatableTables |
#3094 | Add Relations.getUniqueKeys(SchemaDefinition), getUniqueKeys() |
#3095 | Add SchemaDefinition.getTables() |
#3096 | Add Constants.XSD_RUNTIME, NS_RUNTIME, XSD_CODEGEN, NS_CODEGEN |
#3111 | Support multiple Converters for the same <U> type in the code generator |
#3115 | Support hypothetical set function syntax (for CUME_DIST, RANK, DENSE_RANK, PERCENT_RANK) |
#3116 | The jOOQ Scala manual examples use T_BOOK instead of BOOK |
#3125 | Generate default ArrayRecord constructors that don't need a Configuration |
#3130 | Generated UDTRecords should be more similar to generated TableRecords |
#3139 | Add <T1, ..., T[N]> Result<Record[N]<T1, ..., T[N]>> DSLContext.newResult(Field<T1>, ..., Field<T[N]>) |
#3153 | Add a paragraph to the manual explaining classpath behaviour of the standalone code generator |
#3154 | Add code-generation configuration to generate synthetic primary keys for updatable views |
#3169 | Add more ResultQuery.fetchAnyXXX() convenience methods |
#3180 | Add a Java 8 example to the documentation |
#3181 | Update external manual links to point to the JavaSE 8 Javadoc |
#3189 | Add DSL.sequenceByName(String...) |
#3199 | Add some Javadoc to Result.attach() and Result.detach() to explain the semantics |
#3202 | Allow for Pattern.COMMENTS in code generation configuration's regexes |
#3203 | Add DSL.not(Field<Boolean>) as a convenience for DSL.not(Condition) and condition(Field<Boolean>) |
#3204 | Clarify what "fully qualified" means in the context of <include/> and <exclude/> in the code generator configuration |
#3205 | Add DSL.condition(Boolean) as a convenience for condition(Field<Boolean>) |
#3212 | Add support for value types in DefaultRecordMapper, when mapping Record1 types |
#3229 | Add DSLContext.transaction() to implement nested transaction semantics through functional interfaces |
#3230 | Implement TransactionProvider for use with DataSourceConnectionProvider |
#3232 | Add optional <type/> configuration to <customType/> in order to specify different converters for the same Java type |
#3233 | Add DataTypeDefinition.getConverter() |
#3240 | Add DSL.sequence() methods for plain SQL sequence construction |
#3252 | Relax bounds on <R> for DSLContext.batchInsert() |
#3253 | Pull up TableRecord.insert() |
#3264 | Use try-with-resources statements in the manual |
#3265 | Add manual examples for include / exclude that explicitly use schemas (and other fully qualified object names) |
#3275 | Use maven-plugin-annotations in jOOQ-codegen-maven instead of Javadoc tags |
#3286 | Add MySQLDSL.encode(byte[]) and decode(byte[]) |
#3288 | Add DSL.date(String), DSL.time(String), and DSL.timestamp(String), as shortcuts for respective valueOf() methods |
#3305 | Add SQLDialect.families() to access all SQLDialect families |
#3307 | Change internal representation of AbstractRecord to use Object[] and BitSet instead of Value[] |
#3319 | Update the jOOQ LIMIT .. OFFSET manual page |
#3316 | Add RecordContext.recordType() to allow for introspecting record types when implementing RecordListeners |
#3321 | Add support for Oracle's (+) JOIN syntax |
#3322 | Add UpdatableRecord.store(Field<?>...), insert(Field<?>...), update(Field<?>...) |
API changes (backwards-compatible)
#3126 | Deprecate generated ArrayRecord constructors that take a Configuration argument |
#3127 | Deprecate ArrayRecord.set(Array) |
#3128 | Change ArrayRecord.setList(List<? extends E>) into ArrayRecord.set(Collection<? extends E>) |
API changes (backwards-incompatible)
#3247 | InsertSetMoreStep must not extend InsertSetStep |
Behavioural changes (backwards-incompatible)
#3131 | Query.getBindValues() should not return inlined bind values |
#3132 | Quoting identifiers that contain "special characters" may lead to unexpected results when using RenderNameStyle.AS_IS |
#3306 | Let Record.key() return a "copy record", instead of a view to the original record |
Bug fixes
#2335 | SQL syntax error when projecting two columns of the same name along with a LIMIT clause in Oracle |
#2700 | DAO.insert() and other DAO operations do not respect DEFAULT values |
#2973 | Field.in(Collection) should accept wildcard instead of T |
#3011 | Routines do not propagate errors raised from T-SQL with sqljdbc_4.0 |
#3018 | Add <outputSchemaToDefault/> to support "default schemas" during code generation |
#3055 | Add missing MariaDB and MS Access support to the manual |
#3057 | Wrong paths in maven-install.sh and maven-install.bat |
#3060 | Conversion fails for Oracle VARRAY / TABLE types, nested in UDTs |
#3069 | jOOQ calls Clob.free(), which is available only in JDBC 4.0 / Java 1.6 |
#3090 | Bad predicates generated from nullable keys on refresh(), update(), delete() |
#3099 | UpdatableRecord.store() executes INSERT instead of UPDATE when used with nullable composite primary keys |
#3101 | MutablePOJOMapper doesn't work with annotated boolean getters |
#3108 | Local Fields' Converters should be preferred over globally registered Converters |
#3117 | jOOQ illegally generates covariant setters on UDTRecords and UDT Pojos when <pojos/> and <interfaces/> are activated |
#3119 | Upgrade to JUnit 4.11 and omit using deprecated junit.framework.Assert in tests |
#3120 | Outdated link to Spring TX in the manual |
#3122 | Runtime Schema mapping doesn't work for UDT |
#3131 | Query.getBindValues() should not return inlined bind values |
#3133 | Code generation marks all PostgreSQL Fields as having a default value |
#3143 | Bad Javadoc in the org.jooq.tools.json package: JSON tools are not "JSONAware" |
#3147 | Field.sortAsc() and sortDesc() should generate inlined values for sort indirection |
#3155 | Improve documentation of <forcedType>'s <types/> element |
#3156 | "Column ambiguously defined" when emulating derived column lists with duplicate column names |
#3159 | Replace BoneCP with Apache DBCP in examples and manual |
#3161 | Bad XSD version number referenced from jOOQ 3.3 manual |
#3162 | NullPointerException when referencing window name that was not declared |
#3164 | Missing formatting when rendering formatted MERGE statement's SET clause |
#3168 | Bad download link in documentation |
#3176 | Don't generate "assignment-constructors" for POJOs and Records with more than 255 columns |
#3179 | PDF manual's white-on-black code sections are hard to read with Kindle |
#3183 | Add some clarification to the manual's section about the H2 MERGE statement |
#3186 | Bad SQL rendered for FOR UPDATE clause in Firebird |
#3187 | Manual section about Groovy has a couple of Scala references in them |
#3191 | ResultQuery.keepStatement(true) doesn't work correctly with DataSourceConnectionProvider |
#3194 | Avoid using deprecated Maven mojo descriptor @parameter expression="${property}" |
#3195 | IN predicate with subquery cannot have LIMIT .. OFFSET clause in Oracle |
#3200 | Converter does not work when loading CSV files |
#3211 | Dead codegen example POM link in manual |
#3214 | Error when inserting PostgreSQL enum array |
#3217 | Manual was not updated after fixing #2910 |
#3218 | Fix the manual and suggest using DSL.field() instead of DSL.fieldByName() |
#3226 | DefaultConnectionProvider shouldn't use DSL class for DEBUG logging |
#3234 | Connection Leak With BatchCRUD operations |
#3237 | UpdatableRecord.store() executes INSERT instead of UPDATE when nullable primary keys are NULL |
#3241 | Cursor.iterator() does not correctly implement Iterator.next() contract with respect to NoSuchElementException |
#3244 | InsertQuery.setDefaultValues() is not supported by the ACCESS dialect |
#3249 | DSL.selectZero() and DSL.selectOne() should alias column names |
#3267 | Misleading DSLContext.batch() Javadoc. It should be clear that an additional call to execute() is needed. |
#3277 | SQLite DECIMAL(p, s) types are not correctly recognised |
#3282 | inputSchema / outputSchema codegen configuration has no effect in Oracle, if inputSchema is lower-cased |
#3293 | Bad composite foreign key references generated for H2 |
#3294 | DSLContext.renderNamedParameters() doesn't replace ?, ? by :1, :2 in plain SQL QueryParts |
#3297 | Bind variables are erroneously inlined into quoted identifiers, if identifiers contain question marks |
#3300 | UpdatableRecord.store() executes INSERT instead of UPDATE when nullable primary keys are NULL, and the updatablePrimaryKeys setting is active |
#3309 | Don't use "deploy" as Maven <defaultGoal/> |
#3328 | Re-create old DefaultConfiguration constructors for backwards- compatibility |
#3333 | maven-compiler-plugin configuration in jooq-parent pom file uses the deprecated compilerArguments parameter |
#3342 | Cannot INSERT into tables with Firebird BLOB types |
Version 3.3.0 - February 14, 2014
Finally, a new awesome jOOQ release is ready for you to download! The most important feature first:
The SEEK method
We've been blogging about keyset paging before:
- https://blog.jooq.org/faster-sql-paging-with-jooq-using-the-seek-method/
- https://blog.jooq.org/faster-sql-pagination-with-keysets-continued/
Every SQL developer should have this tool in their toolchain. And now, with jOOQ 3.3, we natively support a synthetic SQL clause for you to express keyset paging very easily. jOOQ is the only database software out there to do so!
Gudu Software's SQL 2 jOOQ Parser
We're very happy to announce our collaboration with Gudu Software Ltd who have implemented a very powerful SQL parser and transformer for enterprise databases.
Together with Gudu Software, we have created an Open Source SQL 2 jOOQ parser that takes native SQL statements as input and generates jOOQ code as output.
The source code can be found here:
And our manual features a tutorial here:
We will ship, test and maintain this awesome new addition with our own deliverables. So far, SQL 2 jOOQ supports the MySQL and PostgreSQL dialects and it is in an alpha stadium. Please, community, provide as much feedback as possible to make this great tool rock even more!
Please take note of the fact that the sql2jooq library is Open Source, but it depends on the commercial gsp.jar parser, whose trial licensing terms can be seen here:
Great new SQL Feature Support
We've been looking around for SQL standard and vendor-specific features, such as the WINDOW clause (standard!), CROSS APPLY, OUTER APPLY, LATERAL join, DEFAULTs for inserts, and nice datetime arithmetic functions and emulations thereof.
As always, we've also blogged about all these features. See the following links for more details:
- https://blog.jooq.org/probably-the-coolest-sql-feature-window-functions/
- https://blog.jooq.org/add-lateral-joins-or-cross-apply-to-your-sql-tool-chain/
- https://blog.jooq.org/lesser-known-sql-features-default-values/
- https://blog.jooq.org/youre-very-likely-to-have-gotten-sql-date-time-arithmetic-wrong/
Formal Spring integration support
Spring is one of the most popular frameworks to handle transactions, and it does so very well. With the help of our community, we've established new standards and examples of how to get started very quickly with jOOQ and Spring. See the following resources for details:
- https://www.jooq.org/doc/latest/manual/getting-started/tutorials/jooq-with-spring/
- https://github.com/jOOQ/jOOQ/tree/main/jOOQ-examples/jOOQ-spring-example
Features and improvements
#531 | Add support for the WINDOW clause |
#845 | Add support for the T-SQL and Oracle 12c CROSS APPLY clause |
#846 | Add support for the T-SQL and Oracle 12c OUTER APPLY clause |
#1018 | Add support for PostgreSQL and SQL Server non-standard UPDATE .. FROM clause |
#1070 | Add support for SQL Server table-valued functions |
#1506 | Allow for inserting empty records through INSERT INTO .. DEFAULT VALUES |
#2093 | Add comment functionality from DISQUS to website |
#2246 | Add <T> T DSLContext.fetchValue(Select<Record1<T>>) to support more typesafety when fetching single values |
#2576 | Integrate with Travis-CI to run automated builds |
#2657 | Add support for ORDER BY .. SEEK .. LIMIT to implement the "seek method" for faster offsets |
#2709 | Add Record[N].value1(xx), value2(xx) setter methods |
#2734 | Add support for lateral derived tables |
#2744 | Emulate INSERT .. RETURNING through SELECT FROM FINAL TABLE (INSERT ...) in DB2 |
#2767 | Add support for CUBRID 9.2 features |
#2776 | Add support for the PostgreSQL ONLY clause |
#2778 | Add detailed section to the manual about settings.xml |
#2779 | Add support for LEFT(), RIGHT() functions |
#2780 | Add PostgresDSL.oid(Table<?>) to produce table.oid references |
#2784 | Add DSL.row(Collection<?>) to allow for interacting with collections of values or Fields |
#2790 | Add a Context data map scoped to the current subquery |
#2801 | Mention licensing options from the manual, add help message to jOOQ-Codegen when OSS users try using commercial databases |
#2805 | Add seekAfter() and seekBefore() to allow for paging in both directions |
#2806 | Add ResultQuery.fetchSize() to influence the JDBC Statement's fetch size |
#2809 | Add support for MySQL's MID() function, which is a synonym for SUBSTRING() |
#2810 | Add support for the REVERSE() function, where it is supported |
#2824 | Log 500 records on TRACE level, instead of just 5 |
#2828 | Use a default Database for code generation, in the absence of an explicit database |
#2829 | Enhance Loader API to allow for importing JSON data in addition to CSV data |
#2832 | Add OracleDSL.toChar() |
#2838 | Add more sophisticated CustomField example to the manual |
#2840 | Add DSL.date(), DSL.time(), and DSL.timestamp() to extract date, time, timestamp parts from a TIMESTAMP |
#2844 | Let JAXB emit more warnings when loading the code generation configuration |
#2848 | Add support for infix-notation for bitwise operations |
#2851 | Add some documentation to the manual about custom code sections in generated code |
#2853 | Add DSLContext.fetchFromJSON() |
#2854 | Add a JAX-RS (with Spring) and jOOQ example to the manual |
#2860 | Add manual section about using jOOQ with Groovy |
#2876 | Add some Javadoc about the fact that some SQLDialects are available in commercial distributions only. |
#2883 | Add support for PostgreSQL COUNT(DISTINCT(a, b, ...)) through DSL.countDistinct() |
#2885 | Generated enum values contain extra comma |
#2891 | Add a jOOQ / Spring-TX example to GitHub under jOOQ-examples |
#2894 | Enable automated CI on github |
#2898 | Add DSL.generateSeries(int, Field<Integer>) and (Field<Integer>, int) overloads |
#2900 | Overload MockFileDatabase constructor to allow for Readers, InputStreams, and Strings |
#2909 | Improve manual's jOOQ syntax highlighting: Highlight SQL keywords |
#2912 | Add convenience methods set(Connection), set(DataSource), derive(Connection), derive(DataSource) to DefaultConfiguration |
#2915 | Log JDBC URL in code generator configuration log |
#2921 | Add support for ad-hoc table renaming |
#2931 | Add DSLContext.fetchCount(Table<?>) and fetchCount(Table<?>, Condition) |
#2932 | Retry loading the GenerationTool configuration file with a / prepended if it fails |
#2933 | Add {Result.into|ResultQuery.fetch}{Map|Group}({Field<?>|Field[]}, RecordMapper<R, E>) |
#2944 | Add support for GROUP_CONCAT in SQLite |
#2945 | Deprecate the <generateInstanceFields/> code generation flag |
#2946 | Add a section to the manual explaining how to programmatically configure the code generator |
#2950 | Add Table.getComment() and Field.getComment() to access comment meta information from the schema |
#2969 | Add support for SQL Server SOUNDEX() and DIFFERENCE() functions |
#2970 | Add DSL.isnull() as a synonym for NVL() for the SQL Server dialect |
#2971 | Add DSL.space() to support the SQL Server specific SPACE() function |
#2976 | Add bookmarks to the PDF manual |
#2979 | Add Maven install scripts (.bat and .sh) to deliverables |
#2981 | Add an official Spring / Guice example |
#2984 | Add <R extends Record> Table<R> table(Result<R>) to allow to fetch from / join / etc in-memory tables |
#2985 | Add DSL.values(RowN...) |
#3001 | Add VisitContext.clausesLength() and queryPartsLength() to indicate the depth of the currently visited QueryPart tree |
#3002 | Add the BindVariableAbbreviator VisitListener example to the manual |
#3009 | Add DSL.dateAdd(Field<Date>, Field<? extends Number>, DatePart) and timestampAdd(Field<Timestamp>, Field<? extends Number>, DatePart) for better cross-database datetime arithmetic |
#3015 | Add support for HSQLDB user-defined aggregate functions |
#3044 | Integrate SQL 2 jOOQ beta in deliverable |
API changes (backwards-compatible)
#2811 | Deprecate ResultQuery.fetchLazy(int) - fetchSize is now passed to ResultQuery.fetchSize() not only for lazy fetching |
#2837 | Deprecate code generation configuration's <expressions/> in favour of <expression/> |
#2878 | Deprecate Record.getValue() and Result.getValue() methods that take a defaultValue argument |
#3007 | Add API guarantee to ResultQuery.fetch() methods indicating that all JDBC resources are freed |
API changes (backwards-incompatible)
#2910 | The new matchers configuration cannot be used with Maven |
#3038 | Add RecordListener.exception(RecordContext) and RecordContext.exception() |
Behavioural changes (backwards-incompatible)
#2863 | Remove unnecessarily cached Connection in DataSourceConnectionProvider |
Bug fixes
#2016 | Bad parsing of MySQL ENUM literals by jooq-meta, if they contain special characters |
#2152 | Invalid column type: 16, when binding null as java.lang.Boolean onto a NUMBER(..) column in Oracle |
#2633 | Fix manual to link to appropriate Javadoc |
#2655 | Improve ArrayIndexOutOfBoundsException: -1 error message when unknown field is accessed from a record |
#2658 | Inefficient emulation of row value expression comparison predicates <, <=, >, >=. Factor out predicates for improved index usage |
#2773 | Confusion of Unix vs Windows style line terminators in source code |
#2781 | Disambiguate collisions between enum literals and package names |
#2792 | data(Object, Object) methods do not unset the value if null is passed |
#2795 | Bad Javadoc on DSLContext.fetchOne(String) method |
#2798 | Inconsistent logic executed between Record.setValue(Field<T>, T) and BookRecord.setId(Integer) (generated) |
#2816 | Manual shows wrong DefaultConfiguration constructor call for use with Spring |
#2819 | Invalid SQL rendered for Ingres row value expression predicates |
#2820 | Invalid SQL rendered for Ingres derived column lists |
#2825 | IngresDatabase treats unique keys as primary keys |
#2831 | Bad Javadoc formatting on MySQLDSL's and MariaDBDSL's enumType() method |
#2835 | UpdatableRecord.store() and DSLContext.executeInsert() show different behaviour with respect to NULL value insertion |
#2842 | Sybase CAST(? AS LONG VARCHAR) must not contain a length |
#2845 | AbstractStoreQuery.prepare() does not apply RenderKeywordStyle when specifying column names for return after INSERT |
#2857 | Unnecessary whitespace rendered in USING() clause |
#2858 | Bad example in manual related to stored procedure call |
#2864 | Check if ALL_MVIEW_COMMENTS exists before using it (e.g. against an Oracle 9i database) |
#2866 | Wrong implementation for check if ALL_COLUMNS.DEFAULTED exists |
#2869 | DefaultRecordMapper should attach resulting records according to Settings.attachRecords, if target type implements Attachable |
#2872 | Possible StackOverflowError when using plain SQL tables with inlined QueryParts |
#2879 | An exception in the check constraint loader can cause all constraint loading to fail |
#2881 | Throw IllegalArgumentException when calling SelectQuery.addJoinOnKey() and addJoinUsing() with bad JoinType |
#2887 | jooq-codegen-maven should use a target directory relative to the module |
#2913 | Improve code generator compatibility with PostgreSQL 8.x by removing the selection of INFORMATION_SCHEMA.COLUMNS.IDENTITY_GENERATION |
#2916 | Improve code generator compatibility with PostgreSQL 8.x by avoiding the use of window functions |
#2917 | Improve code generator compatibility with PostgreSQL 8.x by avoiding casting to enum types |
#2922 | Manual Bug: SQL Builder example does not compile |
#2923 | Manual Bug: It is not clear where FK_BOOK_AUTHOR is imported from |
#2926 | Add code-generation support for the MySQL / MariaDB TINYTEXT data type |
#2937 | Fix trailing whitespaces in generated code |
#2942 | Error in the manual: Wrong class linked |
#2956 | Field.isFalse() / isTrue() result in extra parameters |
#2958 | Error when the code-generation database user has insufficient grants to read the "mysql" meta schema |
#2963 | Lower log level for warnings about unknown SQL data types from MetaDataFieldProvider (plain SQL) |
#2977 | Missing parent pom.xml file in deliverables |
#2982 | Variable binding doesn't work in vendor-specific UPDATE t1 JOIN t2 queries, when joined tables are subqueries with bind values |
#2987 | Bind values are not debug-logged for standalone stored procedure or function calls |
#2989 | Inherit complete Record state when calling Record.into(Class<? extends Record>) |
#2994 | Manual Bug: The jOOQ 2.x Table.getFields() method is used, which doesn't exist |
#3013 | The Configuration's RecordMapperProvider is not used when mapping UDTRecords |
#3019 | Bad SQL rendered from HSQLDBDatabase when loading check constraints |
#3023 | DefaultRecordMapper does not map nested UDTs onto nested POJOs |
#3027 | Missing whitespace / newline on emulated multi-value INSERT |
#3036 | RecordListeners don't receive "end" events when exceptions occur |
#3039 | Cannot bind NULL with JDBC Types.BOOLEAN in DB2 |
#3042 | Work around flaws in H2's INFORMATION_SCHEMA.CONSTRAINTS.COLUMN_LIST |
#3046 | UDTRecordImpl.toString() may throw NullPointerException, if custom RecordMapperProvider maps Record to null |
#3048 | Nested UDTs are no longer attached when fetched from queries (as opposed to procedures) |
#3050 | DefaultRecordMapperProvider should implement Serializable |
Version 3.2.0 - October 9, 2013
With the new jOOQ 3.2, apart from introducing great new features, we are changing quite a few things on how we operate. At Data Geekery GmbH, we believe in Open Source. But we also believe in the creative power enabled by commercial software. This is why we have chosen to implement a dual-licensing strategy. Read more about this strategy here:
https://blog.jooq.org/jooq-3-2-offering-commercial-licensing-and-support
But jOOQ 3.2 also ships with great new features! They include:
A new RecordListener SPI which can be hooked into the Configuration in order to control ActiveRecord lifecycle events. This is very useful if you want to initialise some database records prior to inserting new data, or if you want to implement a central ID generation strategy, e.g. by generating Java UUIDs.
A new, experimental VisitListener SPI which can be hooked into the Configuration in order to control jOOQ's complete QueryPart rendering and variable binding lifecycle. Use this powerful SPI to perform custom SQL transformation, e.g. to implement shared-schema multi-tenancy, or a security layer centrally preventing access to certain data.
With this release, the Oracle and DB2 SQL dialect families will now be able to distinguish Oracle 10g, 11g, 12c features, as well as DB2 9.x, 10.x features. This is important as more and more databases start supporting the SQL standard OFFSET .. FETCH clause and other clauses that are emulated by jOOQ.
The code generator has experienced a lot of improvements, mainly including a new MatcherStrategy, which can be configured through Maven or XML code generator configurations. This generator strategy will allow you to implement several regular-expression based naming pattern replacements for all sorts of generated artefacts. This is extremely useful to generate table, record, pojo class name prefixes, suffixes in particular, or to just completely redesign the way the jOOQ code generator generates things.
Features and improvements
#674 | Add <fluentSetters/> code generation flag to let generated setters return this |
#996 | Add support for various Postgres ARRAY operations |
#1079 | Add support for Oracle's FLASHBACK QUERY clause |
#1171 | Add a MatcherStrategy GeneratorStrategy to allow for configurative regex pattern matching and replacement |
#1644 | Add DSL.dual() to explicitly create a DUAL table that works with any dialect |
#1903 | Duplicate Query construction API between DSLContext and DSL |
#2010 | Add listener API to Record / UpdatableRecord |
#2352 | Enhance <ForcedType/> to allow for forcing a type upon all columns / parameters / attributes of a given data type |
#2542 | Add a Keyword type and DSL.keyword(String) to construct it |
#2593 | Add Meta.getPrimaryKeys() |
#2594 | Add primary key and foreign key navigation support in JDBCDatabase |
#2595 | Add implicit conversions from Scala functions to RecordMapper |
#2603 | Add <includeExcludeColumns/> flag to code generation configuration to indicate that <includes/> and <excludes/> shall also match column names |
#2606 | Distinguish ORACLE10G, ORACLE11G, ORACLE12C SQLDialects within the ORACLE family |
#2618 | Document the fact that different packages are generated for different schemas |
#2619 | Add an example ExecuteListener to the manual, showing how UPDATE and DELETE statements without WHERE clause can be aborted |
#2630 | Add DSL.queryPart(String, Object...) and similar methods to create simple plain SQL query parts |
#2652 | Change tutorial to use the common AUTHOR table, instead of POSTS |
#2660 | Add some documentation about jOOQ not supporting operator precedence |
#2665 | Implement SPI for RenderContext listening to allow for custom SQL transformation |
#2666 | Pull up RenderContext.sql(QueryPart) and BindContext.bind(QueryPart) to Context.visit(QueryPart) |
#2667 | Add org.jooq.Clause and let org.jooq.Context listen on start(Clause) and end(Clause) events |
#2676 | Add QueryPartInternal.clause() to allow for QueryParts to return Clause information to org.jooq.Context |
#2689 | Expose a DAO's internal RecordMapper through DAO.mapper() |
#2696 | Provide default implementation for CustomQueryPart.bind() (for all Custom QueryParts) |
#2699 | Generate DEFAULT and NULL metadata information on generated DataTypes |
#2701 | Document the fact that jOOQ sets changed flags to true, even if Record.setValue() sets the value already present in the record |
#2702 | Add DataType.defaulted() and DataType.nullable() |
#2706 | Generate "full" constructors in records, allowing to construct a record with all values set |
#2713 | Add support for custom code sections in generated code |
#2722 | Add DSLContext.newRecord(Field<?>...) to support the creation of custom record types |
#2723 | Add example VisitListener implementation that prevents UPDATE, DELETE statement execution without explicit WHERE clause |
#2724 | The default logger should log the number of affected records, if applicable |
#2725 | Add ExecuteContext.rows() to indicate the number of affected rows in the last executed statement |
#2726 | Add Attachable.detach() |
#2729 | Emulate IS DISTINCT FROM through IS / IS NOT in SQLite |
#2733 | Add the default log4j.xml configuration file to the maven plugin |
#2745 | Generate default constructor and "assignment-constructor" in POJOs |
#2757 | Add support for DB2 10.5 |
#2761 | Add some documentation to the manual showing how GeneratorStrategy SPI is used by jOOQ-codegen |
#2764 | Let CRUD operations be able to perform UPDATEs on primary keys |
#2765 | Add support for a database-agnostic GENERATE_SERIES(FROM, TO) table function |
API changes (backwards-compatible)
#2581 | Deprecate fetchLater() and FutureResult<R> |
#2662 | Deprecate the internal method DSLContext.bind(QueryPart, PreparedStatement) |
#2719 | Change various method(Collection<SortField<?>>) into method(Collection<? extends SortField<?>>) |
Bug fixes
#1908 | Compilation error in generated code when a MySQL procedure and function share the same name and signature |
#2534 | Correctly handle Oracle BLOB and CLOB data types, when fetched through plain SQL |
#2580 | Bad SQL rendered when combining DISTINCT with LIMIT .. OFFSET in DB2, SQL Server |
#2584 | ORA-00904: "SYS"."ALL_PROCEDURES"."OBJECT_TYPE": invalid identifier when running code generation with Oracle 10gR1 |
#2586 | Bad SQL dialect referenced from ASE's and CUBRID's package-info.java |
#2591 | Result.intoGroups() and similar methods create key Records with changed=true |
#2592 | Qualified names created using DSL.name(String...) should not render null or empty string parts |
#2596 | Scala tests don't run with Maven |
#2597 | f1.concat(f2).toString() seems to render unnecessary cast expression |
#2608 | Error in code generator when the sqlite_sequence table is missing |
#2613 | The batch INSERT query example in the manual is no longer correct with jOOQ 3.x |
#2624 | Wrong SQL Server 2012 detection in jOOQ-Meta |
#2628 | Add missing Javadoc to DefaultDSLContext |
#2634 | Minor documentation bug: The MockDataProvider uses toLowerCase() but upper-case SQL keywords |
#2643 | Routine.execute(Configuration) should restore the original routine state after execution |
#2681 | "Type NULL is not supported in dialect MYSQL" when calling Meta.getTables() with MySQL or MariaDB JDBC drivers |
#2690 | Inaccurate runtime xsd versions in 3.1 manual |
#2703 | SQLDialect.getNameLC() and getNameUC() are not NPE-safe |
#2707 | PostgreSQL ENUM ordering is inconsistent with the database |
#2708 | Wrong SQL rendered for CAST(x AS DECIMAL(y, z)). Precision and scale are lost. |
#2712 | Field.equalIgnoreCase(String) method broken for SQL Server |
#2714 | Documentation bug in INSERT statements. Cannot combine Field<?> with String arguments in VALUES() clause |
#2717 | DefaultResultSet compile-time depends on Java 1.7 / JDBC 4.1 |
#2718 | NullPointerException in code generator when a primary key (or foreign key) column is excluded from code generation |
#2720 | Fix the manual's claim that <includes/> accepts comma-separated regular expressions |
#2730 | Immutable Pojo+Interface code generation produces uncompilable pojo |
#2736 | Improve code generator compatibility with PostgreSQL 8.x by testing if pg_catalog.pg_enum and information_schema.attributes exist |
#2753 | DATE_DIFF() with CURRENT_DATE() returns wrong precision in Oracle |
#2755 | Incomplete @Support annotations on OrderedAggregateFunction methods |
#2758 | Duplicate primary key column references generated for DB2 |
#2759 | DSLContext.fetchCount() fails when argument SELECT statement does not explicitly provide column names in SQL Server |
#2760 | org.jooq.Meta should treat MySQL databases as Schema, not as Catalog |
#2766 | Javadoc typo on DSLContext.batchDelete() |
Version 3.1.0 - June 30, 2013
With this release, MariaDB is now finally officially supported by jOOQ! MariaDB is a MySQL fork, which currently has a very similar feature set as its parent. As such forks tend to evolve into different directions very quickly, it makes sense to add formal support in jOOQ.
SQL Server 2012 is another SQL dialect that is now officially supported in jOOQ, allowing to make use of the newly supported ROWS UNBOUNDED PRECEDING and similar windowing clauses, as well as the long awaited OFFSET .. FETCH clause. From now on, jOOQ SQLDialect.family() allows to define a super-set of SQL dialects by the same vendors with only subtle differences.
POJO mapping is taken to the next level. jOOQ opened up its internal DefaultRecordMapper providing useful Record to POJO mapping algorithms. But your custom domain model might be more complex. Instead of creating the next impedance mismatch, trying to foresee your own mapping algorithm needs, jOOQ allows you to inject a RecordMapperProvider into your Configuration, allowing to override record mapping with arbitrary behaviour.
This minor release is also a strong step forward towards a more unified SQL experience, where row value expression IN predicates and comparison predicates are simulated with an equivalent EXISTS predicate. See this blog post for more details: https://blog.jooq.org/sql-query-transformation-fun-predicates-with-row-value-expressions
Note, that for technical reasons, jOOQ 3.0.0 could not yet be integration tested with DB2, Ingres, and Sybase ASE. Consider using jOOQ 2.6, instead
Features and improvements
#552 | Add SQLDialect.family() to group several SQLDialect versions of the same RDBMS |
#742 | Improve MySQL Stored Procedure support using MySQL 5.5's INFORMATION_SCHEMA.PARAMETERS dictionary table |
#833 | Add integration tests for both jconn3 and jTDS JDBC drivers for Sybase and SQL Server |
#963 | Map SQL Server TINYINT to UByte |
#965 | Add support for Sybase SQL Anywhere unsigned number types |
#1373 | Add <T> Field<T> DSL.coerce(Field<?>, DataType<T>) and similar methods, to coerce a field to a given data type (as opposed to casting it) |
#1836 | Document using jOOQ with Spring for transaction support |
#1885 | Add test to count opening and closing of Statements and ResultSets by jOOQ |
#2022 | Add support for SQL Server 2012 windowing clauses in window functions |
#2058 | Add support for the MariaDB database |
#2095 | Document <forcedType/>'s feature of forcing a column onto a SQL type |
#2235 | Add Result<?> DSLContext.fetchFromTXT() to allow for loading results that were exported using Result.format() |
#2236 | Add DSLContext.batch(String...) and batch(String, Object[]...) to easily create batch statements from SQL strings |
#2291 | Add DSLContext.fetchAny(Table, Condition) method and others |
#2299 | Allow for setting ResultSet flags (e.g. ResultSet.TYPE_SCROLL_INSENSITIVE through ResultQuery.resultSetConcurrency(), resultSetType(), resultSetHoldability() |
#2310 | Add DSL.using(Connection) and DSL.using(Connection, Settings) which auto-detect the SQLDialect from the jdbc url |
#2311 | Add Configuration.recordMapperProvider() to override jOOQ's internal default ReflectionMapper |
#2339 | Support CUBRID 9.1's new features |
#2344 | Add a new ControlFlowSignal that is used to explicitly jump out of a control flow |
#2355 | Add support for Postgres / HSQLDB's TRUNCATE [...] RESTART / CONTINUE IDENTITY |
#2357 | Add support for Postgres' TRUNCATE [...] CASCADE statement |
#2395 | Simulate row value expression IN predicate using EXISTS |
#2414 | Add Setting to influence parameter rendering (indexed, named, inlined) |
#2416 | Add Result.intoXML(org.xml.sax.ContentHandler) to generate a SAX event stream from a jOOQ result |
#2423 | Add support for SQL Server 2012 native OFFSET .. FETCH clause |
#2424 | Integration-test jOOQ with the SQLite xerial driver |
#2426 | Add DSLContext.batch(Query, Object[]...) as a convenience for calling batch(Query).bind(Object...).bind(Object...) |
#2427 | Add more Javadoc to ResultQuery.fetchResultSet() explaining that underlying PreparedStatements are closed with ResultSet.close() |
#2428 | Simulate row value expression comparison predicates using EXISTS |
#2430 | Add CustomQueryPart for use with plain SQL and other places |
#2434 | Add Field.compare(Comparator, Select) and Field.compare(Comparator, QuantifiedSelect) to allow for more dynamic SQL |
#2437 | Add RenderContext.paramType() and deprecate RenderContext.inline() and .namedParams() |
#2440 | Expose the DataSource contained in the DataSourceConnectionProvider |
#2441 | Add DSL.cast(Field<?>, XXX) for increased API consistency |
#2446 | Add JDBCUtils.dialect(Connection) to "guess" the jOOQ SQLDialect from a JDBC Connection |
#2466 | Add a public DefaultDSLContext implementation that can be used by users to override the default behaviour |
#2485 | Allow for treating Field<Boolean> as Condition |
#2496 | Add support for SQL Server 2012 sequences |
#2499 | Add JDBCUtils.safeClose(Connection) |
#2509 | Expose CHECK constraints in jOOQ-meta |
#2519 | Add Record.from(Object, Field<?>...) from(Object, String...), from(Object, int...) to copy only a select set of values from a POJO, Array, Map |
#2521 | Add {Row|Record}.fields(Field<?>...), {Row|Record}.fields(String...), {Row|Record}.fields(int...) to extract Field<?>[] from a row or record |
#2527 | Add org.jooq.tools.jdbc.DefaultResultSet to provide a default ResultSet delegation implementation |
#2531 | Add integration tests mapping binary(16) to java.util.UUID |
#2532 | Let batch executions debug-log executed queries |
#2535 | Convert.convert(Object, Class) should support simple casting |
#2547 | Document some SQL language to jOOQ DSL API mapping rules in the manual |
#2566 | Upgrade integration test jTDS version to 1.3.1 |
#2571 | Add a new RecordType<R extends Record> type to make up for the missing recursive type definition on Record |
API changes (backwards-incompatible)
#2468 | API bug: MergeNotMatchedSetStep.set(Field, Select) returns MergeMatchedSetMoreStep instead of MergeNotMatchedSetMoreStep |
Bug fixes
#1520 | Handle Ingres', SQLite, SQL Server's, Sybase ASE's limitations of 1024, 999, 2100 or 2000 maximum bind values per query |
#2135 | Postgres ENUM data type isn't supported correctly, if the ENUM needs full qualification |
#2323 | NullPointerException when calling Schema.getTables() on a meta schema with SQLite |
#2401 | Bad package name generated when <packageName/> contents are not trimmed |
#2404 | Cannot combine <dateAsTimestamp/> with <forcedType/> if both match |
#2412 | jOOQ Meta does not recognise non-uppercase IN, OUT, INOUT keywords in MySQL stored procedures |
#2413 | Suppress warnings in generated code (@SuppressWarnings("all") doesn't suppress "rawtypes" warnings with javac) |
#2418 | RenderContext.data() is not passed on to QueryParts when being rendered |
#2422 | Upgrade RSyntaxTextArea to 2.0.7 |
#2432 | Manual refers to a package-private DefaultConfiguration constructor |
#2443 | AbstractStoreQuery.execute() doesn't correctly operate on the Configuration's ConnectionProvider in SQLite IDENTITY fetching queries |
#2445 | JDBCDatabase doesn't recognise Oracle's VARCHAR2 data type (and other vendor-specific data types) |
#2447 | Tables collected through DSLContext.meta() return duplicate columns if multi-schema environments contain identical tables |
#2449 | JDBCDatabase doesn't use DataType.length(), precision(), and scale() |
#2450 | Cannot set precision on TINYINT, SMALLINT, INT, BIGINT data types |
#2461 | Generator Encoding Error for Database-Objects with Unicode-Names |
#2464 | Bad SQL rendered from DELETE statements with aliased tables |
#2469 | NullPointerException in AbstractResultQuery.fetchOneMap() |
#2477 | MySQL's unsigned types cannot be used in other dialects |
#2478 | IngresDatabase erroneously joins IIINDEXES to get constraint columns, rather than using IIKEYS |
#2494 | Possible null pointer passed to ConnectionProvider.release() |
#2502 | Code generation fails to generate valid java for stored procedures that accept parameters named configuration. |
#2506 | SQLDialectNotSupportedException on DSL.inline(T, Class), when jOOQ's internals are not (yet) properly initialised |
#2515 | Compilation errors when generating code for artefacts that differ only by a trailing underscore(s): A and A_ and A__ |
#2523 | Statement.close() may be called upon previously closed statements |
#2528 | Combining renderFormatted with inlined bind variables will change bind$ values when they contain newlines |
#2562 | Bad SQLDialect reference in Oracle and MySQL package-info.java |
#2569 | Error when rendering SQL Server procedures with Settings.renderSchema == false |
Version 3.0.0 - April 28, 2013
This major release is a great move towards better integration of SQL as a language in Java. Unlike any other database abstraction framework, jOOQ now formally supports the notion of "row value expressions". The jOOQ API uses Xtend-generated API types from Row1 .. Row22, as well as Record1 .. Record22 to bring you even more compile-time typesafety on a record-level.
In SQL, you can typesafely write
SELECT * FROM t WHERE (t.a, t.b) = (1, 2) SELECT * FROM t WHERE (t.a, t.b) OVERLAPS (date1, date2) SELECT * FROM t WHERE (t.a, t.b) IN (SELECT x, y FROM t2) UPDATE t SET (a, b) = (SELECT x, y FROM t2 WHERE ...) INSERT INTO t (a, b) VALUES (1, 2)
In jOOQ, you can now (also typesafely!) write
select().from(t).where(row(t.a, t.b).eq(1, 2)); // Type-check here: -----------------> ^^^^ select().from(t).where(row(t.a, t.b).overlaps(date1, date2)); // Type-check here: ------------------------> ^^^^^^^^^^^^ select().from(t).where(row(t.a, t.b).in(select(t2.x, t2.y).from(t2))); // Type-check here: -------------------------> ^^^^^^^^^^ update(t).set(row(t.a, t.b), select(t2.x, t2.y).where(...)); // Type-check here: --------------> ^^^^^^^^^^ insertInto(t, t.a, t.b).values(1, 2); // Type-check here: ---------> ^^^^
This also applies for existing API, which doesn't involve row value expressions:
select().from(t).where(t.a.eq(select(t2.x).from(t2)); // Type-check here: ---------------> ^^^^ select().from(t).where(t.a.eq(any(select(t2.x).from(t2))); // Type-check here: -------------------> ^^^^ select().from(t).where(t.a.in(select(t2.x).from(t2)); // Type-check here: ---------------> ^^^^
And for UNIONs
select(t1.a, t1.b).from(t1).union(select(t2.a, t2.b).from(t2)); // Type-check here: -------------------> ^^^^^^^^^^
These type-checks are preformed by your Java compiler, considering the generic type information of your SQL statement's Record data types. These include:
- Record1<T1>
- Record2<T1, T2>
- Record3<T1, T2, T3>
- ...
- Record22<T1, T2, T3, .., T22>
The highest degree of typesafety was chosen to be 22, to match Scala's Tuple22, Product22 and Function22 types. Higher degree records are still supported by jOOQ, just without the additional typesafety.
This Record typesafety is applied to
- SELECT statements
- INSERT and MERGE statements: the VALUES() clause
- UPDATE statements: SET A = (SELECT...)
- UPDATE statements with row value expressions: SET (A, B) = (SELECT...)
- Quantified comparison predicates: ANY(SELECT...) and ALL(SELECT...)
- Comparison predicates: = (SELECT...)
- IN predicates: IN (SELECT...)
- BETWEEN predicates: BETWEEN (SELECT...) AND (SELECT...)
- Generated records
- The new VALUES() constructor
- Scala integration for conversion of jOOQ Record[N] to Scala's Tuple[N]
Apart from this major improvement, there had been many minor changes throughout the jOOQ API. Here are some important ones:
- Factory has been split into DSL (static QueryPart construction) and DSLContext (Query execution, "attached" QueryPart construction). This greatly improves the overall DSL experience while allowing for more fine-grained Executor lifecycle control.
- A ConnectionProvider has been introduced as an abstraction of the JDBC Connection lifecycle. The standalone Connection and pooled DataSource modes are still supported, but you can now inject your own ConnectionProvider for more control.
- A lot of performance improvements have been implemented within the jOOQ API removing most of the overhead caused by jOOQ when fetching data from JDBC
- A JDBC Mock API has been added to help you create simple unit tests for your application built on top of jOOQ.
- A VALUES() constructor is now supported, and derived column lists to alias tables and columns in one go.
- The data type API has been greatly simplified. This allowed for the introduction of runtime precision, scale, and length information.
- CRUD has been improved through many more CRUD batch operations, explicit INSERT and UPDATE (in addition to store()), and explicit handling of jOOQ's internal changed flags.
As this is a major release, some backwards-incompatibilities were inevitable. For those users among you, migrating from jOOQ 2.x to 3.0, here are a couple of useful hints: https://www.jooq.org/doc/latest/manual/reference/migrating-to-3.0/
Note, that for technical reasons, jOOQ 3.0.0 could not yet be integration tested with DB2, Ingres, and Sybase ASE. Consider using jOOQ 2.6, instead
Note, that further code generation and model API improvements were postponed to a later release
Note, previous release candidates contained more features, improvements and bug fixes. See their respective sections for details.
Features and improvements
#2410 | Add some more API usage examples to the section about ResultSet fetching |
#2415 | Add Constants.MINOR_VERSION and Constants.FULL_VERSION for internal and external reuse |
Bug fixes
#1998 | Wrong screenshots in the manual's section about code generation. jooq-meta.jar is missing |
#2407 | Fix bad references to pre-3.0 Factory in Javadoc |
Version 3.0.0 (RC3) - April 12, 2013
This major release is a great move towards better integration of SQL as a language in Java. Unlike any other database abstraction framework, jOOQ now formally supports the notion of "row value expressions". The jOOQ API uses Xtend-generated API types from Row1 .. Row22, as well as Record1 .. Record22 to bring you even more compile-time typesafety on a record-level.
See release 3.0.0 for more information.
Features and improvements
#2195 | Remove the standalone tutorial, link to the manual |
#2321 | Implement various Key.toString() methods |
#2329 | Add Javadoc to Configuration.executeListenerProviders() |
#2331 | Add hint to the manual about mvn eclipse:clean and eclipse:eclipse when building jOOQ |
#2363 | Change the readme file to use Markdown |
#2366 | Add org.jooq.util.example package to jOOQ-codegen with some example GeneratorStrategies |
#2372 | Add aliases for arithmetic operators to be able to use Groovy default operator overloading |
#2389 | Make org.jooq.impl.DefaultConfiguration public |
#2392 | Add Configuration.set() methods. They should allow for modifying a Configuration |
#2396 | Add DSL.function(Name, Class, Field...) and DSL.function(Name, DataType, Field...) to allow for custom, fully-qualified function references |
API changes (backwards-compatible)
#2378 | Allow for overriding getIdentity() and getReferences() in CustomTable |
API changes (backwards-incompatible)
#2328 | Remove UpdatableTable marker interface, pulling up methods to Table |
#2342 | Change Configuration.data() to return Map<Object, Object> |
#2343 | Decouple lifecycle of Configuration and ExecuteContext |
#2350 | Do not statically reference a Connection from GenerationTool |
#2353 | Decouple org.jooq.Context from Configuration. Choose composition over inheritance |
#2362 | Decouple org.jooq.DSLContext from Configuration. Choose composition over inheritance |
#2379 | Replace 3.0-RC1 Executor type by a contextual DSL type constructed from DSL.using() |
#2380 | Rename org.jooq.impl.Factory to org.jooq.impl.DSL |
#2382 | Let DAO reference a Configuration instead of a DSLContext |
#2388 | Replace Configuration's List<ExecuteListener> with ExecuteListenerProvider[] to simplify correct and thread-safe client implementations |
#2390 | Change Configuration API to reflect jOOQ-style getter / setter naming |
#2391 | Rename dialect-specific Factories [Dialect]Factory to [Dialect]DSL |
#2399 | Remove support for the USE statement |
Behaviour changes (backwards-incompatible)
#2351 | Relax ConnectionProvider contract, allowing acquire() to return new Connections even before release() is called |
Bug fixes
#1868 | Cursor.close() doesn't terminate the ExecuteListener life cycle |
#2325 | "HsqlException: incompatible data type in conversion" when binding a UUID[] to an HSQLDB prepared statement |
#2327 | Compilation error in generated tables, when a table contains a UNIQUE key but no PRIMARY key |
#2332 | Documentation example regarding DSL.concat() does not compile |
#2336 | jOOQ 3.0 regression: NoClassDefFoundError caused by missing log4j dependency |
#2338 | Tutorial example unclear: There are three artefacts in Maven, not one |
#2346 | org.jooq.Meta's generated Schema and other objects are Serializable, but their enclosed Meta instance is not |
#2347 | Let equals() implementations succeed early on identity |
#2354 | Single page manual display errors on Firefox |
#2361 | Inaccurate Configuration Javadoc explaining wrong ExecuteListener lifecycle |
#2367 | SQLite identifiers that collide with keywords should be quoted |
#2381 | Do not add TableFieldImpl to table in constructor of TableFieldImpl |
#2385 | fetchOne() and fetchLazy() don't terminate the ExecuteListener life cycle when an exception occurs |
#2393 | Fully qualified name not used for user-defined aggregate function |
Version 3.0.0 (RC2) - March 8, 2013
This major release is a great move towards better integration of SQL as a language in Java. Unlike any other database abstraction framework, jOOQ now formally supports the notion of "row value expressions". The jOOQ API uses Xtend-generated API types from Row1 .. Row22, as well as Record1 .. Record22 to bring you even more compile-time typesafety on a record-level.
See subsequent release candidates or release 3.0.0 for more information.
Features and improvements
#2200 | Add Executor.fetchCount(Select<?>) and Select.fetchCount() to replace the projection by a COUNT(*) query |
#2244 | Add section to the manual indicating that the jOOQ generator can only handle schemas of a certain size |
#2255 | Add code generation option to avoid the generation of "global object references" |
#2257 | Add List<IdentityDefinition> Database.getIdentities(SchemaDefinition) for convenience to jooq-meta |
#2258 | Restore private and deprecated versions of the Factory constructors, adding some Javadoc about the changes between jOOQ 2.x and 3.0 |
#2270 | Add section to the manual indicating how to build jOOQ with Maven |
#2272 | Add a paragraph to the manual's preface, explaining "why not just use SQL"? |
#2281 | Add Result<Record> Executor.fetchFromStringData(List<String[]>) in order to reuse logic from fetchFromCSV |
#2285 | Add more verbosity to the code generator, when configured badly |
#2290 | Add Database.getUniqueKeys() and getForeignKeys to jOOQ-meta |
#2297 | Add section to the manual indicating how the various generator flags depend on each other |
#2308 | Do not generate "final" Tables.java, UniqueKeys.java, etc. |
Bug fixes
#2212 | "code size too large" in generated SchemaImpl, when the number of tables exceeds 15k |
#2238 | Code generation runs extremely slow for large schemas (Inefficient DefaultRelations.getUniqueKeys() and getForeignKeys() methods) |
#2239 | Code generation runs extremely slow for large schemas (Inefficient AbstractDatabase.filterSchema() methods) |
#2252 | ArrayIndexOutOfBoundsException, when rendering plain SQL that is terminated by a comment |
#2259 | RenderMapping has no effect, if not supplied to the Executor constructor |
#2262 | RenderSchema has no effect, if not supplied to the Executor constructor |
#2267 | SQLDialectNotSupportedException: Type class org.postgis.PGgeometry is not supported in dialect null, when binding PG* objects |
#2271 | jOOQ Unit tests fail when not run in CET / CEST |
#2273 | Tutorial bug, referencing wrong Maven dependency. jOOQ 3.0.0 is not yet released, only RC1 |
#2276 | Wrong MockDataProvider manual example |
#2278 | Postgres (UUID and other) ARRAY types aren't correctly inlined as string literals |
#2279 | UUIDs aren't correctly deserialised from Postgres UDTs |
#2280 | Improve supported formats for MockFileDatabase |
#2283 | Class loading issues in GenerationTool when called by Gradle |
#2294 | Compilation errors when code generator is configured with <daos>true</daos> and <relations>false</relations> |
#2298 | Suppress warnings in generated code (@SuppressWarnings("all") doesn't work with javac) |
#2312 | Annotate org.jooq.Support with java.lang.annotation.Documented to make it part of the public API (in Javadoc) |
#2314 | Outdated GenerationTool Javadoc |
Version 3.0.0 (RC1) - February 16, 2013
This major release is a great move towards better integration of SQL as a language in Java. Unlike any other database abstraction framework, jOOQ now formally supports the notion of "row value expressions". The jOOQ API uses Xtend-generated API types from Row1 .. Row22, as well as Record1 .. Record22 to bring you even more compile-time typesafety on a record-level.
See subsequent release candidates or release 3.0.0 for more information.
Features and improvements
#456 | Add runtime support for PRECISION, SCALE, and LENGTH attributes |
#834 | Add support for the Firebird / Postgres UPDATE .. RETURNING clause |
#915 | Add <T1, T2, ..., T[N]> Table<Record[N]<T1, T2, ..., T[N]>> Factory.values(Row[N]<T1, T2, ..., T[N]>...), to create ad-hoc tables from data |
#1038 | Introduce new type GroupField for cube(), rollup() and groupingSets() functions. Accept only GroupField... in groupBy() clauses |
#1097 | Add org.jooq.Catalog, a type modelling an entity combining several org.jooq.Schema |
#1144 | Overload Executor.fetch[One|Lazy](ResultSet, X...) with X being Field<?>, DataType<?>, Class<?> |
#1178 | Allow for treating Condition as Field<Boolean> |
#1583 | Add support for row value expressions in UPDATE statements: UPDATE .. SET (A, B, C) = (SELECT X, Y, Z) |
#1624 | Add support for java.util.UUID as a <T> type |
#1663 | Document RenderContext and make it part of the public API |
#1686 | Add UpdatableRecord.insert() and update() |
#1689 | Generate <E> E into(E) and <E> R from(E) methods to generated records |
#1690 | Add UpdatableRecord.key() returning a Record holding PK values |
#1695 | Add Factory.all() and Factory.any() to create quantified expressions |
#1703 | Add Executor.batchDelete(UpdatableRecord<?>...) to mass-delete a set of UpdatableRecords |
#1801 | Add Table.as(String, String...) to allow for creating a table aliases (correlation names) with derived column lists |
#1874 | Add Record1, Record2, ... Record[N] similar to Row1, Row2, ... Row[N] to support record type-safety |
#1897 | Add a section to the manual about the migration to jOOQ 3.0 |
#1899 | Make some JDBC-related utility methods publicly available in org.jooq.tools.jdbc.JDBCUtils |
#1902 | Duplicate SELECT API between Executor and Factory |
#1904 | Add Executor.fetch(ResultQuery), Executor.execute(Query), and similar methods |
#1905 | Add Row[N].equal(Select<? extends Record[N]>) and similar methods |
#1906 | Use Xtend to generate Row[N], Record[N] and other [N]-related API code artefacts |
#1914 | Document the fact that SELECT * is performed by leaving the SELECT list empty |
#1917 | Add support for CUBRID 9.0's window functions and MERGE statement |
#1918 | Let generated Records implement Record[N] if applicable |
#1919 | Support higher degrees of Row[N] and Record[N] types. Match Scala's max degree of 22 |
#1920 | Add more implicit defs in order to treat Record[N] as Scala's Tuple[N] |
#1923 | Add Record.intoResultSet() to create a single-record JDBC ResultSet from a Record |
#1924 | Add support for CUBRID 9.0's ENUM data type |
#1932 | Generate Javadocs for Table constructors |
#1934 | Improve generated Record Javadoc |
#1951 | Add support for the SQL Server WITH (...) table hints |
#1966 | Add Row[N].equal(Record[N]) and similar convenience methods |
#1967 | Document using MySQL's SQL_CALC_FOUND_ROWS as an Oracle hint |
#1968 | Add org.jooq.Meta returned from Executor.meta() to return a wrapped JDBC DatabaseMetaData object |
#1972 | Move MySQLFactory.md5() to Factory and simulate it for Oracle |
#1973 | Add Executor.fetchOne(ResultSet) |
#1975 | Add Result.sort{Asc|Desc}(int) and (String) to order by field index / name |
#1981 | Add support for DB2 CGTT and MQT |
#1983 | Improve the Javadoc on Table.as() and Field.as() to hint at case-sensitivity and RenderNameStyle |
#1984 | Add ResultQuery.fetchOneInto() |
#1986 | Add Record.fromMap() as the inverse operation of Record.intoMap() |
#1987 | Allow for reading data from arrays, Maps through Record.from() |
#1988 | Add Record.fromArray() as the inverse operation of Record.intoArray() |
#1989 | Add Record.changed(Field<?>), changed(int), changed(String) to check whether a single field's value has changed |
#1990 | Add <T> T Record.original(Field<T>), original(int), original(String) to get a Field's original value |
#1991 | Reflect changed flag in Result.toString() (and thus also Record.toString()) |
#1999 | Add Record.changed(boolean) changed(Field<?>, boolean) changed(int, boolean) changed(String, boolean) as setters for the changed flag |
#2000 | Add Record.reset(), reset(Field<?>), reset(int), reset(String) to restore original values in a record |
#2008 | Add elementFormDefault="qualified" to XSD specifications to allow for XML validation of jOOQ configuration files |
#2020 | Let org.jooq.ExecuteListener extend java.util.EventListener |
#2021 | Add UpdatableRecord.refresh(Field<?>...) to allow for refreshing a subset of the Record's values |
#2027 | Document semantic versioning rules as understood by jOOQ |
#2028 | Add Batch.size() to indicate the number of queries that will be executed by a batch operation |
#2030 | Add reusable wrapper types for JDBC Connection, Statement, ResultSet, etc. |
#2044 | Add various TableRecord.fetchParent(...), fetchChild(...) and fetchChildren(...) methods to follow foreign key relationships |
#2049 | Add gt() / ge() / lt() / le() to Row[N] types |
#2052 | Add [not]Between[Symmetric]() to Row[N] types |
#2053 | Add is[Not]Null() to Row[N] types |
#2066 | Add Executor.extractBindValues(QueryPart), extractParams(QueryPart) to extract bind values in the context of an Executor (i.e. Configuration) |
#2072 | Let UDTRecordImpl and ArrayRecordImpl.toString() return a valid constructor expression |
#2078 | Add Postgres to @Support annotation of SelectForUpdateWaitStep.wait() |
#2079 | Support generation of bean validation annotations on records and interfaces |
#2089 | Generate an "empty" DefaultSchema for those databases that do not have any schema (CUBRID, Firebird, SQLite) |
#2094 | Add unit tests for org.jooq.tools.Convert |
#2107 | Let Record implement Comparable |
#2111 | Improve org.jooq.Record Javadoc, to explain the various Record subtypes |
#2112 | Add Row.types() and Row.dataTypes() as a convenience |
#2113 | Document Record.hashCode() and equals() through Javadoc |
#2133 | Allow for mapping <outputSchema/> to "" (empty) in order to avoid the generation of a schema |
#2156 | Add Row.type(int), type(String), dataType(int), dataType(String) for convenience |
#2158 | Add Executor.fetchLazy(Table) and fetchLazy(Table, Condition) for convenience |
#2159 | Let ExecuteListener extend Serializable |
#2160 | Add Executor.batchUpdate(UpdatableRecord<?>...) to mass-update a set of UpdatableRecords |
#2161 | Add Executor.batchInsert(UpdatableRecord<?>...) to mass-insert a set of UpdatableRecords |
#2162 | Add some more Javadoc to JooqLogger |
#2170 | Add 0.0 and 1.0 to Convert.FALSE_VALUES and Convert.TRUE_VALUES |
#2171 | Allow for converting booleans to numbers through org.jooq.tools.Convert: TRUE => 1, FALSE => 0 |
#2172 | Add <T> set(Field<T>, Select<? extends Record1<T>>) methods to UPDATE, MERGE and INSERT statements |
#2176 | Add hint in code generation, when an unsupported, old database version is being used (e.g. MS SQL Server 2000) |
#2177 | Add ResultQuery.intern() and Result.intern() for string interning in result sets |
#2179 | Add Javadoc to QueryPart.hashCode() and equals() |
#2199 | Allow for INSERT and UPDATE of pre-existing records through SET [ Record ] clauses |
#2202 | Add Mock JDBC objects for unit testing with jOOQ |
#2203 | Add Executor.map(Schema) and Executor.map(Table) as a convenience to apply runtime schema mapping |
#2204 | Add BatchBindStep.bind(Object[][]) to bind lots of bind values at a time |
#2205 | Add <R> Result<R> Executor.newResult(Table<R>) to generate custom results |
API changes (backwards-compatible)
#1309 | Let Factory.val() return Param<T> instead of Field<T> |
#2031 | Change union(Select<R>) and similar methods to union(Select<? extends R>) |
#2157 | Change the bounds of various <H extends RecordHandler<R>> H fetchInto(H handler) methods to RecordHandler<? super R> |
#2197 | Relax bounds on Factory.groupingSets(Collection<Field<?>>...) to Collection<? extends Field<?>>... |
#2206 | Relax bounds of R on Executor.newRecord() from TableRecord<R> to Record |
API changes (backwards-incompatible)
#1118 | Remove support for the code generation ant task |
#1254 | Move org.jooq.tools.unsigned contents to org.jooq.types (along with the INTERVAL types) |
#1374 | Relax usage of generic <? extends T>. Replace by <T> where data types are involved. |
#1533 | Extract Executor API from Factory. Let Factory contain only static QueryPart factory methods |
#1549 | Externalise connection lifecycle through new ConnectionProvider |
#1649 | Remove support for code generation from pre-jOOQ 2.0 .properties file |
#1740 | Remove support for generated master data enums |
#1875 | Add generic <R extends Record> type to SelectXXXStep DSL type hierarchy for increased tuple type-safety |
#1887 | Remove all deprecated code |
#1894 | Remove constructors from dialect-specific factories |
#1907 | Remove FactoryOperations, push its API down to org.jooq.impl.Executor |
#1921 | Add <T1, T2, ..., T[N]> InsertValuesStep[N]<R, T1, T2, ..., T[N]> Executor.insertInto(Table<R>, Field<T1>, Field<T2>, ..., Field<TN>) |
#1926 | Add <T1, T2, ..., T[N]> MergeXXXStep<R, T1, T2, ..., T[N]> Executor.mergeInto(Table<?>, Field<T1>, Field<T2>, ..., Field<TN>) |
#1977 | Remove the confusing concept of having a "main key" as opposed to a "primary key" |
#2042 | Remove generated setters, setting foreign key values from records |
#2043 | Remove generated navigation methods |
#2060 | Remove redundant SimpleSelectXXX API |
#2117 | Remove the FieldProvider marker interface. Simplify the FieldProvider API |
#2119 | Rename Row.getDegree() to Row.size() |
Behaviour changes (backwards-incompatible)
#1235 | SQLite BIGINT data type erroneously maps to java.math.BigInteger |
#1578 | Change configuration of ExecuteListeners in Configuration. Listeners instances should be provided, not classes |
#2076 | Stop "supporting" comma-separated regular expressions in the code generator configuration |
#2088 | Do not treat CUBRID "owner" as schema in generated code |
Bug fixes
#1170 | Improve performance on jOOQ's reflection usage |
#1626 | Explicitly implement hashCode() and equals() in some additional QueryParts |
#1886 | Query.bind() has no effect when Query.keepStatement(true) and StatementType.STATIC_STATEMENT are combined |
#1890 | Bad Postgres array serialisation when " or \ characters are contained in a String[] |
#1938 | Improve AbstractField.hashCode() and AbstractTable.hashCode() and similar, as these two are called very often |
#1942 | Inefficient call to String.split() in StringUtils.toCamelCase() leads to non-negligible performance overhead in POJO transformation calls |
#1937 | Inefficient implementations of AbstractDataType.equals() and hashCode() |
#1954 | Bad SQL rendered when combining ORDER BY [ some-function ] with LIMIT .. OFFSET in DB2, SQL Server |
#1958 | Bad SQL rendered for OVER (ORDER BY [ some-function ]) for SQL Server and Sybase |
#1974 | Optimise various Executor.fetchOne() methods, which consume the whole ResultSet before throwing an InvalidResultException |
#1979 | Thread safety issue in org.jooq.impl.FieldList |
#1982 | Change RenderNameStyle.UPPER, LOWER, AS_IS to quote literals if needed |
#1992 | Bad reference to org.jooq.debug.[impl].DebugListener in the manual |
#1993 | Bad code generated when the same table name exists in multiple schemas in SQL Server |
#1995 | Record.original() values aren't updated after a Record.store() operation |
#1997 | Review the manual's tutorial for integrity |
#2001 | Named Params are treated as null literals on right sides of comparisons |
#2007 | Bad type coercion on the right hand side of a comparison predicate, when the left hand side is Field<Object> |
#2011 | Implement some micro-optimisations in DefaultRenderContext |
#2025 | Correctly handle multiple foreign keys defined on the same column |
#2045 | Bad hashCode calculation when Records contain arrays or byte[] |
#2055 | MySQL's UPDATE [t1] JOIN [t2] syntax can cause syntax errors as column references are not fully qualified |
#2057 | Cannot properly extract bind values for LIMIT .. OFFSET clause from a SELECT statement |
#2063 | jOOQ-meta loads Firebird composite unique key columns in wrong order |
#2073 | The code generator's <dateAsTimestamp/> flag doesn't affect Oracle VARRAY and TABLE types |
#2082 | Oracle PIVOT expression doesn't bind any variables of a derived table being pivoted |
#2085 | java.lang.NoSuchMethodError: org.apache.log4j.Logger.isTraceEnabled()Z when logger dependency is missing |
#2086 | SQL syntax error when aliasing outcome of a relational division |
#2091 | CUBRID doesn't really have a NVARCHAR data type |
#2098 | NullPointerException when org.jooq.impl.EnumConverter converts null |
#2104 | SQLite code generation treats multi-column primary keys like multiple single-column unique keys |
#2108 | SQLite returns NULL for val(new Date(0)).add(-1) and some other date time arithmetic expressions |
#2128 | Misleading Javadoc in Factory / Executor.selectCount() |
#2137 | Failure to assign a value to a record pojo for a column with a composite type when using select into. |
#2139 | batchStore with Postgres composite types incorrectly reuses values from the first record. |
#2140 | No table java mapping generated using maven plugin - missing inputSchema in postgres |
#2143 | UnsupportedOperationException when binding UDTRecord in batchStore() for Oracle |
#2144 | Improve AbstractField.equals() and AbstractTable.equals() and similar, as these two are called very often |
#2145 | Improve QueryPartList.removeNulls() as this is called very often |
#2154 | Generated Records should access values by index, not by field, for performance reasons |
#2165 | Add H2 database definitions to the jOOQ-scala module (to prevent compilation errors) |
#2167 | Convert.convert("xx", boolean.class) returns null, instead of false |
#2178 | Improve FieldList. Avoid creating excessive array lists, where simple (immutable) Field<?>[] are sufficient |
#2180 | Optimise DAOImpl by using the new ReflectionMapper instead of calling Record.into() all the time |
#2187 | Change all Javadoc <h3/> tags to <h5/> (To fix Java 7 standard Javadoc style layout issues) |
#2210 | Executor.fetchFromCSV() shouldn't mark resulting records as "changed" |
#2215 | Improve example in the "jOOQ for CRUD" section. Use only columns from the sample database |
#2223 | SQL injection is possible in org.jooq.impl.Val, if client code doesn't correctly enforce generic typesafety, and bind variables are inlined |
#2227 | Field.in(T...) doesn't convert argument values to the Field's type |
Version 2.6.0 - October 26, 2012
This release has a new main feature: the type-safe support for row value expressions also known as tuples - up to a degree of 8. The API is formed in a similar way as pre-existing tuple support in languages like C# or Scala.
jOOQ's Scala integration has also been improved through the new jOOQ-Scala module, which provides some useful implicit defs for operator overloading. Future versions of jOOQ-Scala may experiment with Scala 2.10's Macros
This release also ships with a lot of new deprecation to help you prepare for the upcoming major release.
Minor feature improvements include:
- Lots of new fetchGroups() and intoGroups() methods, thanks to Ivan Dugic
- JDBC execution control support, such as cancel(), maxRows(), queryTimeout()
- Allowing for re-using JDBC PreparedStatement between Query executions
- Support for the SQL standard OVERLAPS predicate
- A new RecordMapper, similar to the existing RecordHandler
Features and improvements
#385 | Allow for keeping open statements in a Query |
#600 | Add support for Oracle / SQL Standard linear regression functions |
#1058 | Add <T1, T2, .. TN> Factory.row(T1, T2, .. TN) and Factory.row( Field<T1>, Field<T2> ... Field<TN>) to allow for creating tuples / rows |
#1077 | Add support for the SQL standard OVERLAPS predicate |
#1245 | Improve formatting for DECIMAL data types in Result.format(). Nicely align the decimal point and reserve space on both sides |
#1484 | Let XJC-generated artefacts implement Cloneable |
#1527 | Support for converting String to java.net.URL, java.net.URI, and java.io.File |
#1674 | Export data types with Result.formatXML() and Result.formatJSON() exports |
#1679 | Add Factory.table(String, QueryPart...) |
#1708 | Add <T, E> Map<T, List<E>> ResultQuery.fetchGroups(Field<T>, Class<E>) |
#1709 | Add Map<Record, Result<R>> ResultQuery.fetchGroups(Field<?>[]) |
#1710 | Add <E> Map<Record, List<E>> ResultQuery.fetchGroups(Field<?>[], Class<E>) |
#1719 | Make logic from ResultQuery.fetchArray() available in Result.intoArray() |
#1728 | Add support for the MySQL COUNT(DISTINCT expr, expr...) aggregate function syntax |
#1744 | Add support for the CUBRID DECR() function |
#1756 | Add RecordMapper<E>, similar to RecordHandler<R>, mapping records to custom types |
#1762 | Add package-info.java to add Javadoc documentation to all packages |
#1766 | Simulate row comparisons where they are not supported |
#1773 | Add a new jOOQ-Scala project and jooq-scala artefactId, to contain jOOQ extensions in the Scala language |
#1782 | Move JAXB bindings out of XSD, in order to support more advanced bindings |
#1783 | Generate @SuppressWarnings("all") in jOOQ-generated artefacts |
#1784 | Enhance the BETWEEN predicate, introducing the AND keyword |
#1810 | Add <T, E> Map<T, E> ResultQuery.fetchMap(Field<T>, Class<E>) and Result.intoMap(Field<T>, Class<E>) |
#1816 | Add support for materialized views in Oracle's code generator |
#1828 | Reduce log level for Factory deserialisation to TRACE |
#1837 | Add support for @java.beans.ConstructorProperties when fetching into immutable POJOs |
#1841 | Add SortField Field.sort(SortOrder) to allow for dynamic sorting |
#1842 | Add Condition Field.compare(Comparator, Field<T>) to allow for dynamic comparisons |
#1844 | Add Table<Record> Table.join(TableLike<?>, JoinType) to allow for dynamic joining |
#1845 | Add Factory.schemaByName(String) for plain SQL schemata |
#1848 | Add Record.changed() to indicate whether a Record contains "dirty" values |
#1849 | Add Record.original() to obtain the originally fetched values from a Record |
#1854 | Add ResultQuery.maxRows(int) to limit the number of actually fetched records |
#1855 | Add Query.cancel() to support for interrupting statements prematurely |
#1856 | Add Query.queryTimeout(int) to support for JDBC's Statement.setQueryTimeout() |
API changes (backwards-compatible)
#1800 | Deprecate AliasProvider |
#1807 | Result.intoArray() declares "throws MappingException", which isn't true |
#1839 | Deprecate the various Result.getValuesAs[Type] and Record.getValueAs[Type] methods |
#1840 | Deprecate org.jooq.Store |
#1866 | Deprecate [Schema-Name]Factory, remove reference to it from the tutorials |
#1869 | Deprecate org.jooq.NamedQueryPart |
#1870 | Deprecate org.jooq.NamedTypeProviderQueryPart |
#1872 | Improve jOOQ's RenderContext pretty printing behaviour |
#1881 | Deprecate ConditionProvider, OrderProvider, LockProvider types |
Bug fixes
#1593 | Factory.field("{1} + {0} + {0}", val(1), val(2)) doesn't work. Cannot re-use / re-order placeholders |
#1720 | Improve performance by using Record.getValue(int) instead of Record.getValue(Field) internally, where more than one value is retrieved from a record |
#1751 | Result.intoResultSet() generates wrong ResultSetMetaData if runtime schema mapping is applied |
#1764 | Add missing @Support({ ... FIREBIRD ... }) annotations |
#1768 | NullPointerException when DAO.fetchOne() returns no record |
#1774 | QueryPart.toString() does not load default settings from classpath |
#1786 | Fix SEQUENCE support for Firebird |
#1791 | Log a table's input/output names, and PK name when generating code |
#1792 | Factory.fieldByName() and tableByName() do not correctly escape quotes |
#1797 | SQL syntax errors when plain SQL contains comments with question marks and SQL is executed as StatementType.STATIC_STATEMENT |
#1802 | Result.into(Table) doesn't work correctly, if the same field name appears twice in Result |
#1806 | Let Record.toString() wrap the record in a temporary Result and call Result.toString() instead |
#1819 | MappingException in Record.into(Class), when POJO setters have applicable names but non-applicable argument types |
#1820 | Cannot fetch into non-public POJO classes. Their members / getters / setters should be made accessible |
#1829 | Factory.execute(String) may cause errors when plain SQL returns results |
#1830 | Allow for passing null or empty arrays to intoMap(Field[]) and intoGroups(Field[]) |
#1850 | Record.equals() returns true as soon as both records hold a "null" value for a given field |
#1860 | Bad Results returned from plain SQL "select *" queries, if several selected columns share the same name |
#1876 | NULL constraint violation when storing a copied record |
Version 2.5.0 - August 26, 2012
Welcome to another great database integration in jOOQ: Firebird! This is one of the more popular open source SQL databases out there, with a rich feature set, including the SQL standard MERGE statement.
Apart from this, the main new features are:
- Optimistic locking. jOOQ's UpdatableRecord API transparently implements optimistic locking on its store() and delete() methods. By default, the in-memory record is compared with the one in the database at write time. But you can also let jOOQ handle incremented VERSION or TIMESTAMP columns for you.
- Oracle feature increment. Many nice Oracle features are now supported: user-defined aggregates, regular expressions, Oracle Text, CONNECT_BY_ROOT and ORDER SIBLINGS BY clausess, partitioned outer joins and more
- jOOQ's convenience API has been greatly enhanced. This includes many improved fetch methods and new short forms for equal=eq, notEqual=ne, greaterThan=gt, etc. to better align jOOQ with JPA, XSL, QueryDSL and many other tools that abbreviate these keywords
- Many types and methods have been deprecated to help you foresee the upcoming changes in jOOQ 3.0
Please consider also the updated manual with its new, more user-friendly structure
Features and improvements
#430 | Add support for the Firebird database |
#457 | Add support for Oracle user-defined AGGREGATE functions |
#620 | Add support for the SQL:2008 standard LIKE_REGEX operator |
#722 | Remove casting of bind values in Ingres |
#727 | Simulate RPAD and LPAD in SQLite |
#816 | Add support for Oracle Text functions |
#1339 | Add option to generate immutable pojos |
#1547 | Support "optimistic locking" in UpdatableRecord.store() and delete() |
#1552 | Generate fetchBy[ColumnName] methods in generated DAO classes |
#1553 | Add some Javadoc to document the difference between using a Factory with a Connection or with a DataSource |
#1556 | Add javax.validation API to full deliverable |
#1565 | Add Factory.connectByRoot(Field<?>) to support the Oracle CONNECT_BY_ROOT pseudo column |
#1570 | Add Factory.condition(String, QueryPart...) similar to Factory.field(String, QueryPart...) |
#1582 | Add support for Oracle's ORDER SIBLINGS BY clause, in combination with CONNECT BY |
#1586 | Add missing constructors taking DataSource to dialect-specific factories |
#1587 | Generate missing constructors taking DataSource in schema-specific factories |
#1595 | Simulate REPEAT() in SQLite |
#1596 | Add support for optimistic locking using generated information about "timestamp" or "version" columns |
#1627 | Handle NULL in CSV imports/exports |
#1645 | Add support for Oracle's PARTITION BY clause in OUTER JOINs |
#1657 | Reorganise the manual |
#1664 | By default, activate <relations/> in the code generator |
#1665 | Add support for the empty GROUP BY () clause |
#1675 | Add support for the SQL standard IS [NOT] DISTINCT FROM predicate |
#1680 | Overload all plain SQL DSL methods to also accept QueryPart arguments |
#1681 | Simulate empty GROUP BY () clause in Sybase ASE and Ingres, joining a dummy table and grouping by a constant field |
#1684 | Add <attachRecords/> Setting to indicate that fetched records shouldn't be automatically "attached" |
#1685 | Improve Javadoc of Attachable.attach(). Document how "detaching" works |
#1688 | Add <E> E Record.into(E) as a complement to <E> E Record.into(Class<E>) |
#1692 | Replace Factory.executeInsert(), Factory.executeUpdate() and similar methods with more succinct variants |
#1696 | Add short versions of comparison predicate methods, such as eq, ne, gt, ge, lt, le |
#1698 | Add support for the SQL standard BETWEEN SYMMETRIC predicate |
#1701 | Add Factory.not(Condition) as a synonym for Condition.not() |
#1704 | Document the behaviour of Factory.newRecord(Table<?>, Object) and Record.from(Object) with respect to UpdatableRecord.store() |
#1707 | Add <K> Map<K, Result<R>> ResultQuery.fetchGroups(Field<K>) and Result.intoGroups(Field<K>) |
#1712 | Add <T extends Comparable<? super T>> Result.sortAsc .sortDesc(Field<T>) |
#1713 | Add <T> Result.sortAsc, .sortDesc(Field<T>, Comparator<? super T>) |
#1714 | Add Result.sortAsc, .sortDesc(Comparator<? super R>) |
#1718 | Document usage of InvalidResultException on the ResultQuery.fetchXXX() Javadocs |
#1721 | Add <K, V> Map<K, List<V>> ResultQuery.fetchGroups(Field<K>, Field<V>) and Result.intoGroups(Field<K>, Field<V>) |
#1722 | ResultQuery.fetchArray(int) and .fetchArray(String) should return a typed array, even if this cannot be checked by the compiler |
#1723 | Add Factory.fetchLazy(ResultSet) |
API changes (backwards-compatible)
#1544 | Remove Attachable interface from QueryPart hierarchy |
#1579 | Deprecate org.jooq.Type |
#1580 | Deprecate org.jooq.SchemaProvider |
#1638 | Deprecate org.jooq.ArrayRecord.createArray() |
#1639 | Deprecate org.jooq.Adapter |
#1687 | Let Cursor.fetchInto(Table<Z>) return Result<Z> instead of List<Z> |
#1736 | Deprecate TableRecord.{store|refresh|delete}Using() methods as being part of jOOQ's internal API |
#1741 | Deprecate org.jooq.MasterDataType |
Bug fixes
#1572 | Use Thread.currentThread().getContextClassLoader() to load ExecuteListener classes as a workaround for experienced class loading problems when using OSGi |
#1584 | Code generation error with Oracle UDT static functions |
#1632 | Improve the performance of various DefaultRenderContext methods, by locally caching Settings values |
#1633 | Improve the performance of CursorImpl.CursorIterator by setting Record values by index rather than by Field |
#1635 | Improve the performance of Factory.fetch(ResultSet) by caching data type normalisation regex in FieldTypeHelper |
#1650 | jOOR Fix #16: Can't call Reflect.create(A, B, null) |
#1660 | Factory.renderContext().castMode(CastMode.NEVER).render(query) doesn't work. CastMode is not applied |
#1667 | Bad variable binding when NULLS FIRST, NULLS LAST is simulated in SQL Server and other databases |
#1673 | Result.formatXML() and Result.intoXML() do not render namespaces correctly |
#1683 | Oracle code generation regression for 10g. No such column ALL_PROCEDURES.OBJECT_ID |
#1693 | Cannot bind UDT values from other schemata to stored procedures |
#1730 | Compilation errors in SQLite generated code when flag <instanceFields/> is set to true |
Version 2.4.0 - July 8, 2012
This release's main new feature is jOOQ's added convenience in Factory initialisation for those users who get their database connectivity through JDBC DataSources. If supplied with a DataSource, a jOOQ Factory will handle the Connection lifecycle internally, closing the Connection when no longer needed.
The H2 MERGE statement syntax is now supported and simulated in other databases, for those users that prefer its more intuitive syntax over the SQL standard.
The code generator now also allows for generating interfaces and DAOs per table. DAO generation was previous discussed on the user group and seen in a competitor product called OneWebSQL.
The jOOQ Console now supports breakpoints for even more effective SQL development
Features and improvements
#1141 | Add Result.intoResultSet() to wrap a Result in a JDBC ResultSet |
#1253 | Avoid JDBC escape syntax for date/time literals |
#1280 | Generate DAO classes and interfaces for POJOs |
#1404 | Document the lifecycle of an ExecuteListener in the Javadoc |
#1411 | Add support for Postgres "any" data type (with quotes!). This seems to map well to java.lang.Object |
#1418 | Support case-insensitive schema names in code generation |
#1419 | Add some WARN-level logging when the source-code generator doesn't generate any artefacts |
#1423 | Add Field.likeIgnoreCase() to support Postgres' ILIKE operator |
#1424 | Add Factory(DataSource) and similar constructors |
#1427 | Add Factory.batchStore(Collection<? extends UpdatableRecord<?>>) for convenience |
#1428 | Add DataType.convert(Object...) and DataType.convert(Collection<?>) for convenience |
#1431 | Add org.jooq.Name Factory.name(String) to contruct QueryParts that are escaped according to Settings.getRenderNameStyle() |
#1432 | Add Factory.fetch(String, QueryPart...) and Factory.execute(String, QueryPart...) and similar methods to support arbitrary QueryParts in plain SQL |
#1434 | Add UniqueKeyDefinition.isPrimaryKey() for completeness |
#1438 | Add Result<Record> Factory.fetchFromCSV(String) |
#1440 | Add top-level pom.xml for jooq-parent artefact (GitHub Issue #14) |
#1446 | Converting arbitrary strings to Number / Date should return null, instead of throwing an exception |
#1449 | Generate some meaningful Javadoc into the generated [schema-name]Factory classes |
#1454 | Add line breaks to generated Javadoc where appropriate |
#1463 | Add option to let generated Record / POJO objects implement a common generated interface |
#1470 | Support interface types in ResultQuery.fetchInto(Class), Result.into(Class), and Record.into(Class) methods, returning a proxy |
#1471 | Upgrade internal jOOR dependency to jOOR 0.9.4 |
#1473 | Add IdentityDefinition to jooq-meta |
#1501 | Add support for conversion of String to java.sql.{Date, Time, Timestamp}. GitHub issue #22 |
#1504 | Document behaviour of fetch() and fetchOne() in case jOOQ cannot fetch actual records |
#1509 | Minor improvements in the generator source code. GitHub pull request #23 |
#1510 | Generate additional setters for foreign keys, accepting records as arguments |
#1521 | Expose Connection methods, such as commit(), rollback() and similar transaction-related methods in Factory |
#1523 | Support ROW_NUMBER() OVER() for the latest version of Derby and H2, which support it |
#1524 | Simulate ROW_NUMBER() OVER() in HSQLDB using ROWNUM() |
#1528 | Let generated interfaces extend Serializable |
#1532 | Clarify the lifecycle of Configuration.data in the Javadoc |
#1534 | Generate more meaningful Javadoc where "an uncommented item" stands now |
#1536 | Add documentation to the FOR UPDATE OF clause, indicating that DB2 may have stricter requirements regarding updatability of fields |
#1541 | Add support for the H2 MERGE syntax - GitHub Issue #18 |
#1542 | Simulate the H2 MERGE syntax in other dialects supporting the SQL standard MERGE statement - GitHub Issue #18 |
#1545 | Website and Documentation anchors should be links to themselves, visually recognisable |
Features and improvements (jOOQ Console)
#1398 | Allow for adding breakpoints in jOOQ Console |
API changes (backwards-compatible)
#1408 | Relax bounds of <R> in Factory.truncate() to Record, instead of TableRecord |
#1429 | Change Convert.convert(List, XXX) to accept Collection instead of List |
Bug fixes
#1020 | Improve Oracle's LIMIT .. OFFSET clause simulation. GitHub Issue #16 |
#1358 | Compilation errors in generated source code when Oracle overloaded procedures collide with procedures that end with numbers |
#1437 | Error in Javadoc of FactoryOperations.fetchOne(). This method may return null |
#1441 | Performance issue with AbstractDataType.convert(Object). Avoid conversions when they're obviously unneeded |
#1448 | Handle String to Enum conversion (when Java Enums are stored as Strings in the database) - GitHub issue #15 |
#1459 | Generated Keys.java static class too large (static initialiser can become bigger than 64kb) |
#1460 | Table.getReferencesTo(Table) doesn't work correctly for aliased tables |
#1461 | Exception when rendering of {fn datetimeadd(...)} for HSQLDB and Derby |
#1462 | Document missing GeneratorStrategy features, such as getJavaClassImplements() |
#1465 | Custom generator strategy's printImplements() is called with Mode == RECORD for tables |
#1478 | Caching SQLDialect in AbstractDatabase heavily improves code generation performance |
#1483 | Inefficient cloning of default settings using JAXB unmarshalling leads to non-negligible overall overhead. Use serialisation instead (short of a useful XJC clone plugin) |
#1489 | Fix manual where it claims to throw SQLExceptions |
#1490 | Compilation error when a SQL Server stored procedure has a parameter named "value" |
#1493 | Bad syntax for SELECT /*+hint*/ DISTINCT ... in Oracle |
#1498 | jOOQ does not compile using JDK 7 / JDBC 4.1. GitHub Issue #24 |
#1499 | Generated members of Tables.java are not final |
#1505 | Bad exception message when ON DUPLICATE KEY IGNORE cannot be simulated |
#1515 | Splitting of large NOT IN conditions is wrong. The parts should be connected with AND, not with OR |
#1522 | fetch().into(Table) doesn't initialise records correctly, such that subsequent calls to store() will execute an INSERT, rather than an UPDATE |
#1525 | Generate missing Javadoc to getters for procedure OUT parameters |
#1529 | Factory.batchStore() logs all single statements to DEBUG output. Find a more accurate log output |
#1537 | Factory.batchStore() renders bad SQL for Postgres. The RETURNING clause is not allowed in batch INSERTs |
Version 2.3.1 - May 11, 2012
This is an important patch release fixing some regressions in the code generator for the Postgres dialect. With 2.3.0, it was no longer possible to generate schemata of which the database user was not the owner.Bug fixes
#1334 | Fix inaccurate simulation of TRUNC(number, decimals) for Derby |
#1403 | Documentation bug: ctx.statement() can be replaced in executeStart(). This is not documented |
#1406 | Compilation errors in generated source code when Postgres stored procedure parameter is called "NAME" |
#1407 | Compilation errors in generated source code when Postgres data-type is "any" (with quotes!) |
#1409 | Postgres code generation broken when not connecting with the owner of a schema |
Version 2.3.0 - May 6, 2012
This is a minor feature increment release, featuring many useful API enhancements, some new functions, some new syntax support elements, improved source code generation and a lot of improvements on the jOOQ Console, thanks to Christopher Deckers.
The updated jOOQ Console now allows for filtering incoming statements directly on the server side, using regular expression filters on statement text and other features. These improvements are a part of a general strategy to introduce breakpoints and more sophisticated debugging capability to the jOOQ Console.
Features and improvements
#597 | Add support for Oracle KEEP (DENSE_RANK FIRST...) aggregate function clause |
#910 | Add ExecuteListener extension to allow for overriding exception translator to handle vendor-specific error codes |
#1286 | Add "renderSchema" flag to Settings, to completely disable rendering of schema names |
#1293 | Generate setter methods for JAXB annotated configuration properties |
#1295 | Add support for MySQL's INSERT IGNORE clause |
#1296 | Simulate the FOR UPDATE clause for SQL Server, CUBRID, using JDBC's ResultSet.CONCUR_UPDATABLE |
#1302 | Add Factory.inline() to allow for flagging inline-only "bind values" |
#1303 | Add connection-less Factory constructors for convenience, when jOOQ is only used as a SQL query builder |
#1304 | Add option to generate JSR-303 @NotNull and @Size annotations to generated POJO's |
#1307 | Let HSQLDB dialect render NVL2() as NVL2() instead of CASE expression |
#1312 | Allow for omitting <inputSchema/>, and generate all available schemata in that case |
#1315 | Let generated factories use their associated Schema as the Settings' RenderMapping's defaultSchema |
#1319 | Move jooq-spring's FactoryProxy to the core jooq project |
#1322 | Add Factory.dateAdd() and timestampAdd() for convenience |
#1327 | Add DataType.isLob() |
#1328 | Add Field<String> inline(char), inline(Character), inline(CharSequence) for convenience |
#1333 | Add support for the Oracle TRUNC function, for numeric arithmetic |
#1336 | Let Record.into(Class<?>) and similar methods accept "immutable" classes, i.e. setter-less classes that take several constructor arguments |
#1340 | Use Constructor.setAccessible(true), if no default constructor is available on the target type of Record.into(Class<?>) |
#1342 | Improve Javadoc on Factory.function(). Document arguments |
#1349 | Add support for the CUBRID Click-Counter INCR() |
#1352 | Allow for creating syntax-error and SQL-injection safe qualifiers for org.jooq.Field and org.jooq.Table |
#1361 | Add Factory.batchStore(TableRecord<?>...), to allow for batch UPDATE/INSERTs of many records |
#1367 | Make configured ExecuteListeners default constructors accessible |
#1366 | Let org.jooq.Batch extend Serializable |
#1378 | Upgrade internal jOOR dependency to jOOR 0.9.3 |
#1379 | Upgrade internal jOOU dependency to jOOU 0.9.1 |
#1390 | Add RenderContext.qualify() to indicate whether QueryParts should render qualified versions of themselves or not |
Features and improvements (jOOQ Console)
#1242 | Upgrade jOOQ Console dependency on RSyntaxTextArea from 1.5 to 2.0.2 |
#1249 | Allow for filtering incoming statements in jOOQ Console |
#1393 | Implement a communication protocol between Console server types and Console client types to allow for more sophisticated functionality |
API changes (backwards-compatible)
#1310 | Deprecate Factory.literal() in favor of Factory.inline(), and Factory.field() |
#1368 | Promote AbstractQuery.isExecutable() to the public API |
Bug fixes
#989 | INSERT and UPDATE statements always render non-qualified, escaped field names. This may cause trouble when using plain SQL fields |
#1109 | Standalone TABLE or VARRAY types are not correctly initialised before referencing tables load them |
#1279 | NullPointerException when leaving <inputSchema/> empty |
#1283 | The LIKE escape character needs escaping, too, in contains(), startsWith(), endsWith() |
#1306 | Add missing INTERVAL data types to HSQLDBDataType |
#1308 | Oracle's DataTypeDefinition reports the length of a BLOB / CLOB data type to be 4000 |
#1313 | <includes/> and <excludes/> match only table names, not fully qualified names |
#1323 | Add support for byte[] in Postgres UDTs |
#1324 | Code generation error in Oracle 10g when generating stored procedures |
#1326 | Error when deserialising BLOBs from Oracle UDTs |
#1329 | NullPointerException when passing null to timestampDiff(Field, Field) |
#1343 | Regression in insertInto(...).values(...). Cannot pass Field<?> to values() |
#1344 | Initialise Result ArrayLists to their expected size, if that size is known. |
#1360 | jOOR issue 12: "Don't reset the accessible flag to false, if setting it to true is required, to avoid race conditions in concurrency contexts" |
#1371 | Missing conversion when using unsafe Field<?> types in BATCH statements |
#1376 | Oracle UDTs in REF CURSORs are not deserialised correctly from procedure OUT parameters |
#1377 | Oracle UDTs are not deserialised correctly when the same UDT name is present in multiple schemata |
#1394 | NullPointerException when omitting <generate/> element in code generation configuration |
Version 2.2.1 - April 12, 2012
This is a minor patch release, fixing some issues related to the code generation of the new CUBRID integration as well as other, minor issues. Upgrade if you're using CUBRID
Bug fixes
#1287 | Remove oracle.sql dependency also from OSGi information in pom.xml |
#1288 | SQL syntax errors from sequences when using RenderMapping with defaultSchema |
#1289 | DefaultBindContext logs as Util.class |
#1297 | Compilation error in CUBRID generated artefacts referencing OBJECT types |
#1298 | Avoid source code generation errors when generating code for unknown, dialect-specific data types |
Version 2.2.0 - April 09, 2012
Finally, jOOQ has added support for another database, and a very promising one, that is. https://www.cubrid.org is a surprisingly original mixture of a relational and object-oriented database where tables and classes are synonyms, so are records and instances. The CUBRID database has a high level of compatibility with MySQL and is aimed at MySQL users wanting more performance for their web applications. For details, see the slides here:
https://www.slideshare.net/cubrid/growing-in-the-wild-the-story-by-cubrid-database-developers
jOOQ is proud to have become a CUBRID partner, looking forward to further cooperation with CUBRID in the near future.
Apart from that, jOOQ now fully supports SQL standard INTERVAL data types. With JDBC and JPA lacking official support for this, jOOQ aims for becoming the tool of choice for vendor-specific date time arithmetic. True INTERVAL data type support is given in HSQLDB, Ingres, Oracle, Postgres databases. Besides that, CUBRID and MySQL support INTERVAL data type arguments in functions. In other dialects, jOOQ simulates DATEADD(), TIMESTAMPADD(), DATEDIFF(), TIMESTAMPDIFF().
For jOOQ's OLAP friends, there is now also support for the Oracle LISTAGG function (LIST() in Sybase, XMLAGG() in DB2, STRING_AGG() in Postgres, GROUP_CONCAT() in CUBRID, H2, HSQLDB, MySQL). LISTAGG is an "ordered aggregate function", meaning that the aggregation is done using a specific ordering. Keep an eye out for more such function support in future versions.
Features and improvements
#566 | Add support for INTERVAL data types |
#585 | Add support for DATE, TIME and INTERVAL arithmetic |
#1183 | Add support for DEFAULT values in Oracle stored procedure parameters |
#1243 | Let generated POJOs (and Records) extend base classes and implement interfaces |
#1252 | Avoid JDBC escape syntax for Oracle stored procedure calls. Generate PL/SQL syntax, instead |
#1255 | Let generated Tables contain a public default constructor to be able to extend those classes - Github issue #12 |
#1257 | Add CUBRID support |
#1268 | Add Factory.field(String, QueryPart...) to generate custom clauses |
#1269 | Add YEAR(), MONTH(), DAY(), HOUR(), MINUTE(), SECOND() function support as shortcuts for EXTRACT() |
#1273 | Simulate GROUP_CONCAT() aggregate function using Oracle's LISTAGG() function, where available |
#1274 | Add support for the Oracle LISTAGG(...) WITHIN GROUP (ORDER BY ..) [ OVER (..) ] aggregate / analytic function |
#1275 | Simulate Sybase LIST() aggregate function using Oracle's LISTAGG() function |
#1276 | Simulate Oracle's LISTAGG() in DB2 using XMLAGG(), SUBSTR() and CONCAT() |
#1278 | DEBUG log both executed SQL and SQL with inlined bind values |
API changes (backwards-compatible)
#1262 | Pull up OracleFactory.prior() and other CONNECT BY related methods to Factory |
Bug fixes
#1241 | Wrong variable binding when comparing CHAR columns in Derby and DB2 without explicit casting to VARCHAR |
#1244 | Cannot override class name in GeneratorStrategy in Mode.POJO |
#1248 | Setting both <records>false</records> and <relations>true</relations> leads to compilation errors |
#1256 | Fixed code generation issue with H2 user defined functions returning VARCHAR |
#1263 | Pass fetchsizes <= 0 to the JDBC driver (for vendor- specific MySQL compatibility) |
#1270 | Most databases allow for multiple identical foreign keys. This leads to compilation errors in generated source code |
Version 2.1.0 - March 18, 2012
With this version, jOOQ attempts to follow versioning rules imposed by semantic versioning: https://semver.org/ There will be 1 minor release per month, and a couple of patch releases per year, depending on popular demand
The main improvements for this release include
- The possibility of providing jOOQ with a custom type mapping. You can now define your own Converter types that are used by jOOQ to map a database's SQLDataTypes to your custom types. This is particularly useful for Java's enums. Read more about custom converters in the manual: https://www.jooq.org/manual/ADVANCED/CustomTypes/
- There are a lot of new runtime configuration options to control the SQL style of SQL rendered by jOOQ. You can now specify whether table/column names should be quoted / capitalised / lower-cased, whether SQL keywords should be capitalised or not, etc...
- The handling of NULL has been improved in favour of using jOOQ as a SQL builder library (e.g. along with Spring for execution) NULL is no longer inlined, but bound as a variable.
- jOOQ now supports simulation of the relational division operation using an intuitive syntax. Read more about the relational division here: https://en.wikipedia.org/wiki/Relational_algebra#Division
Features and improvements
#161 | Add runtime configuration to pretty print rendered SQL |
#349 | Add SQLite relations support |
#491 | Add runtime configuration for SQL keyword style (upper case, lower case) |
#521 | Add runtime configuration for SQL reference style (upper case, lower case, as-is, quoted) |
#1150 | Add code generation option to disable generation of records |
#1181 | Add support for SQL Server data types timestamp and rowversion |
#1188 | Load default Settings from the classpath at /jooq-settings.xml, or from -Dorg.jooq.settings |
#1193 | Specify main-class in jOOQ Console's manifest.mf and include dependency in jar file |
#1194 | Add ColumnDefinition.isNullable() |
#1202 | Add support for the relational division operation: A.divideBy(B).on(A.ID.equal(B.A_ID)).returning(A.X, ...) |
#1207 | Add Factory.batch(Collection<? extends Query>) for convenience |
#1208 | Render @javax.persistence.Column(nullable = false) property, if available |
#1209 | Render @javax.persistence.Column(length, precision, scale) properties, if available |
#1215 | Add org.jooq.Converter<T, U> for custom type mapping |
#1216 | Overload Record, Result.getValue() and .setValue() methods to accept a Converter |
#1217 | Add EnumConverter as a base type for custom enum converters |
#1218 | Add code generation options to generate <customTypes/> referencing a Java type and a Converter |
#1224 | Add DataTypeDefinition.getLength() to jooq-meta's type system |
#1233 | Support custom JDBC properties for jooq-codegen |
#1234 | Add Database.getTable(SchemaDefinition, String, boolean) to fetch tables case-insensitively |
#1239 | Add Factory.fetchLazy(String, Object...) |
API changes (backwards-compatible)
#1191 | Deprecate ConfigurationRegistry and replace by equivalent ExecuteListener feature |
#1219 | API Bug: Cannot use LIMIT .. OFFSET along with FOR UPDATE |
Bug fixes
#625 | Remove dependency from generated Routines to the generator's SQLDialect |
#1128 | NULL is inlined in INSERT statement instead of binding it as a variable. This can cause issues when using jOOQ with Spring |
#1137 | Exclude MySQL column-level enum types when that column is overridden by a <forcedType/> |
#1158 | Derby cannot handle inlined NULL literals in some contexts |
#1180 | Execute BatchMultiple (multi-query batch query), when executing BatchSimple (single-query, multi-bind-value query) with StatementType == STATIC_STATEMENT |
#1189 | TableMapping regression for SQLite database |
#1190 | Cannot store SQLite records when using StatementType.STATIC_STATEMENT |
#1199 | Table.getFields() returns an internal representation of a table's field list. Make generated tables immutable! |
#1200 | Internal API leak exposed through covariance in AbstractType.getFields() |
#1211 | Enforce method name disambiguation also when using custom strategies in jooq-codegen |
#1212 | Enforce identifier disambiguation also when using custom strategies in jooq-codegen |
#1221 | Incorrect ExecuteListener invocation for INSERT .. RETURNING. executeStart() and executeEnd() are omitted |
#1223 | Cache ExecuteListener classes for performance |
#1225 | Bind NULL byte[] as java.sql.Types.BINARY instead of BLOB in Postgres, to avoid errors |
#1226 | Bind NULL UDTs with their associated type name in Oracle |
#1232 | SQLException when Factory.fetch() does not return a ResultSet |
#1237 | Don't generate enum classes for columns in MySQL tables that are excluded from code generation |
Version 2.0.5 - February 26, 2012
This release finally introduced basic runtime configuration features for the jOOQ Factory. This configuration now includes:
- Execute listener and SQL tracing support. jOOQ allows you to hook your own listeners into jOOQ's query execution engine to be notified of all sorts of events
- The existing SchemaMapping features. They are now part of the runtime configuration
- StatementType settings. Specify whether a Factory should execute java.sql.PreparedStatements (with bind variables) or static java.sql.Statements with inlined variables.
The runtime configuration is documented here:
https://www.jooq.org/manual/JOOQ/Factory/
The listener and tracing support has been requested by Christopher Deckers, a new jOOQ user who has had the courtesy to contribute the new jOOQ Console, which is documented here:
https://www.jooq.org/manual/ADVANCED/ExecuteListener/
Apart from that, another long-requested feature is now fully implemented: The GeneratorStrategy, allowing for custom naming strategies in generated source code. This will allow for generating custom table / record class name prefixes / suffixes, as well as overriding the default behaviour for rendering UPPER, lower and CamelCase artefacts. See the manual for details:
https://www.jooq.org/manual/META/Configuration/
Features and improvements
#93 | Add Field.equalIgnoreCase(), Field.notEqualIgnoreCase() |
#408 | Add class prefixes, suffixes and other options to the code generator |
#492 | Add runtime configuration |
#1107 | Let Field.contains() support the Postgres ARRAY @> ARRAY operator |
#1140 | Add ResultQuery.fetchResultSet() to return the underlying JDBC result set |
#1143 | Add Result.isNotEmpty() for convenience |
#1145 | Add runtime configuration to specify whether jOOQ should execute java.sql.PreparedStatement (with bind variables) or a java.sql.Statement (with inlined parameters) |
#1146 | Add Query.getSQL(boolean) to indicate that bind values should be inlined (as a convenience for Factory.renderInlined(QueryPart)) |
#1148 | Add Cursor.resultSet() to expose the underlying ResultSet |
#1149 | Allow for optional https://www.jooq.org/xsd/jooq-codegen-2.0.4.xsd namespace in jooq-codegen configuration |
#1152 | Add <E extends java.lang.Enum<E> & org.jooq.EnumType> E MySQLFactory.enumType(Class<E>, int) for enum reverse lookups of MySQL-specific enums |
#1159 | Support matching numbers with LIKE, e.g. ID LIKE '%33%' |
#1160 | Implement Field.contains(), .startsWith(), .endsWith() for numeric values, too |
#1161 | Use reflection to remove compile-time dependency on ojdbc for creating ARRAYs |
#1162 | Integrate jOOR into jOOQ for simpler reflection |
#1164 | Distinguish between Definition.getInputName(), .getOutputName() |
#1165 | Add constraint name to generated javadoc |
#1167 | Trivial issue with org.jooq.Factory.exists Javadoc - GitHub issue #10 |
#1169 | Add Configuration.setData(), getData() to convey custom data in a configuration's lifecycle |
#1172 | Add runtime configuration to deactivate JooqLogger |
#1177 | Add jOOQ-Console module to jOOQ |
#1184 | Add DataType.isArray() |
API changes (backwards-compatible)
#1142 | Rename Result.exportXML() to Result.intoXML() to stay more consistent |
#1151 | Deprecate SchemaMapping in favour of new runtime configuration |
Bug fixes
#978 | Schema.getTables() and similar methods return empty lists when Schema is mapped with SchemaMapping |
#1153 | Bad inlining of booleans in Sybase ASE / DB2 / Oracle SQL Server / SQLite |
#1154 | Bad inlining of byte[] in most dialects |
#1155 | byte[] are erroneously converted to String when using Record.intoArray() |
#1156 | Bad inlining of DATE / TIME / TIMESTAMP data types in Ingres (and other dialects, when the setting differs from the default) |
#1166 | Some generated Javadoc uses naming strategy or plain output name, instead of qualified output name |
#1168 | Oracle packages are generated as static, instead of static final |
#1175 | Factory.use() seems to render SQL with the Schema name still present |
#1179 | Oracle-generated ArrayRecords need a reference to org.jooq.Schema to read TABLE of OBJECT from stored procedures |
Test cases
#1147 | Add integration tests for executing SQL generated using Factory.renderInlined() |
Version 2.0.4 - February 12, 2012
This release introduced many improvements to source code generation. These improvements include:
- Maven and standalone code generation now use the same XML configuration, which is read by jOOQ-codegen using JAXB. This allows for more complex configuration elements in the future
- jOOQ-codegen can now handle multi-schema databases and generate code for tables referencing tables from other schemata. This is integration tested against the SQL Server AdventureWorks database
- jOOQ now allows to generate simple POJOs in addition to Records and to annotate both POJOs and Records with JPA annotations such as @Entity, @Table, @Id, @Column, @UniqueConstraint, etc.
You can migrate your existing .properties configuration by running > org.jooq.util.GenerationTool /your.properties migrate
Besides that, there is a lot of ongoing work to improve the integration of Oracle's TABLE and VARRAY types.
Features and improvements
#8 | Add JPA annotations to generated POJOs / Records |
#282 | Add support for multi-schema databases |
#287 | Add support for Oracle TABLE types |
#395 | Use XML configuration file instead of properties file |
#1089 | Add Field.contains(), .startsWith(), .endsWith() as a convenience for Field.like() (including escaping) |
#1092 | Move master data table configuration from generator.generate to generator.database namespace |
#1093 | Add support for generator.strategy in Maven source code generation |
#1094 | Add support for generator.database.date-as-timestamp in Maven source code generation |
#1095 | Move generator.generate.unsigned-types to generator.database namespace |
#1096 | Add support for generator.generate.unsigned-types in Maven source code generation |
#1103 | Add support for SQL Server data type uniqueidentifier |
#1106 | Add Factory.escape(Field<String>, char) for use with LIKE |
#1108 | Add support for multi-schema databases using Maven code generation |
#1115 | Add support for Oracle VARRAY/TABLE of OBJECT types |
#1127 | Add support for POJO classes generation |
#1129 | Allow for using Param in LIMIT .. OFFSET clauses |
#1132 | Add RenderContext.castMode() to allow for avoiding casts where this is not really needed |
#1136 | Add generation option to enable/disable generating navigation methods |
Bug fixes
#1099 | Derby generated artefacts are not sorted alphabetically |
#1101 | Internal API leak exposed through covariance in AbstractTable.joinXXX() methods |
#1110 | VARRAY element type information is lost when unnesting VARRAY's in Oracle |
#1111 | VARRAY element type information is lost when unnesting VARRAY's returned from functions in Oracle |
#1114 | Syntax error when unnesting TABLE of OBJECT in Oracle. The unnested table contains several columns but jOOQ only unnests "COLUMN_VALUE" |
#1117 | NullPointerException when passing an ArrayRecord containing a null array to a stored function in Oracle |
#1125 | Postgres needs casting for date time data types in queries like SELECT ? FROM DUAL |
#1131 | DB2: [Noauthorized routine named "LIKE" of type "FUNCTION" having compatible arguments was found] when using Field.like(concat(x, y)) |
#1133 | Compilation errors in generated source code if the same constraint name exists in several schemata |
#1134 | NullPointerException in code generation when a foreign key constraint references a table from another schema that is not being generated |
#1135 | Generated Javadoc references inputSchema instead of outputSchema |
Test cases
#1009 | Add more integration tests for proper handling of java.sql.Date, Time, Timestamp |
#1090 | Run jOOQ tests against AdventureWorks SQL Server sample database |
#1105 | Add integration tests for multi-schema source code generation and querying |
#1122 | The 10k lines of integration test code are too heavy for the compiler. Create test modules with fewer lines of code, each. |
Version 2.0.3 - January 29, 2012
This release focuses on increased compatibility between various SQL dialect integrations as far as ARRAY and JOIN support is concerned:
- ARRAY types are only available in H2, HSQLDB, Oracle, Postgres. Nevertheless, they can be somewhat simulated in other dialects using nested selects with UNION ALL. Increased compatibility leads to a nicer API, where ARRAYs are used along with ALL/ANY quantifiers, for instance.
- JOIN syntaxes can be quite powerful in SQL. Apart from simulating NATURAL JOIN, JOIN USING clauses, as well as a synthetic "KEY JOIN" syntax, jOOQ now also supports nesting JOIN expressions to create more complex table sources. See a recent blog post on the subject here:
https://blog.jooq.org/lets-revise-the-sql-from-clause/
Features and improvements
#578 | Add KEY JOIN syntax to simulate joining using generated foreign keys |
#577 | Simulate NATURAL JOIN syntax, where this is unavailable |
#582 | Simulate JOIN USING syntax, where this is unavailable |
#671 | Allow for nesting JOIN clauses |
#676 | Add Table.join() methods to create more flexible table sources |
#993 | Add Field.equalAny(T[]), .equalAny(Field<T[]>) methods |
#1048 | Simulate <op> <quantifier> (array) syntax for dialects that do not support arrays |
#1051 | Add Factory.execute(String, Object...) as a convenience method for Factory.query(...).execute() |
#1055 | Simulate Factory.table(Object[]) and table(List<?>) using UNION ALL in dialects that do not support arrays |
#1060 | Improve debug logging of H2 arrays. The syntax is not ARRAY[1, 2], but (1, 2) |
#1065 | Add OracleFactory.sysContext(String, String) to support Oracle's SYS_CONTEXT function |
#1069 | Add support for INSERT INTO table(field1, field2, ...) SELECT syntax - as opposed to the existing INSERT INTO table SELECT |
#1072 | Add support for LIKE .. ESCAPE .. syntax |
#1074 | Add Field.notBetween(T, T) for convenience |
#1080 | Add support for JDBC's Statement.setFetchSize() in ResultQuery.fetchLazy() |
#1082 | Add some more DEBUG logging in AbstractResultQuery |
API changes (backwards-compatible)
#1059 | Change SelectFromStep.from(Collection<TableLike<?>>) to from(Collection<? extends TableLike<?>>) |
API changes (backwards-incompatible)
#1087 | Change the NTILE function to return Field<Integer> instead of Field<BigDecimal> |
Bug fixes
#1071 | Make Sequence Serializable |
#1081 | Derby error in NULL handling when simulating unnested arrays that contain NULL values |
#1084 | Bind index mismatch in val(null).equal(null) and in val(null).notEqual(null) |
#1091 | Add missing @Support annotations on Table.crossJoin() methods |
Test cases
#1026 | Add integration tests for NTILE window function and document compatibility |
#1073 | Add integration tests for NOT IN queries holding NULL arguments |
Version 2.0.2 - January 8, 2012
This is a maintenance release for jOOQ 2.0. The main improvements include
- The whole jOOQ API is now annotated with a new org.jooq.Support annotation to help you assess whether a certain SQL clause is available in your database or not. This is particularly useful when your application should support several databases at once (e.g. MySQL, Postgres, Oracle)
- The Oracle PIVOT clause is now formally supported for advanced statistical queries in Oracle. This clause will be simulated in other dialects in the future.
- The DATE data type can be mapped to TIMESTAMP. This important when you query a legacy Oracle database, where DATE columns can also contain time information
- Several convenience methods have been added for more fluent syntax, when using plain SQL result queries, subqueries as tables, or when unnesting arrays in ANY() and ALL() quantifiers
Features and improvements
#595 | Add support for Oracle's PIVOT clause |
#869 | Add support for using ANY, ALL with arrays, not just with subselects |
#1007 | Formally document the API methods to indicate whether something is supported by any given SQL dialect |
#1011 | Add code generation configuration parameter to avoid generating @Generated annotation |
#1019 | Render LIMIT x OFFSET y also for MySQL, instead of LIMIT y, x |
#1022 | Add missing Sybase ASE implementation for Factory.use() |
#1024 | Add Factory.resultQuery(String, Object...) to allow for arbitrary execution modes of plain SQL queries (lazy, later, into, array, etc) |
#1025 | Add missing SQLite implementation for Factory.deg() and Factory.rad() |
#1033 | Generate table comments into generated Tables.java as Javadoc |
#1040 | Add Object[][] Result.intoArray() and Object[] Record.intoArray() for convenience. Let <E> E Record.into(Class<E>) also support array types. |
#1041 | Add <R> Table<R> Factory.table(Select<R>) convenience method for more fluency |
#1042 | Add support for DISTINCT keyword in SUM, AVG, MIN, MAX aggregate functions |
#1046 | Generate Ingres table and column comments in generated source code (only Ingres 10) |
API changes (backwards-compatible)
#1050 | Deprecate usage of SOME quantifier in predicates, such as equalSome() |
API changes (backwards-incompatible)
#1036 | Fixed API typo in WindowsRowsStep.rowsBetweenUnboundedFollwing() |
#1037 | The fluent API allows for JOIN clauses without FROM clause |
Bug fixes
#1010 | The MERGE INTO .. WHEN NOT MATCHED THEN INSERT .. syntax may cause type-safety issues in some databases. VALUES should be converted before binding |
#1014 | FindBugs: Latent risk of infinite recursion due to typo in QueryPartList.retainAll(); |
#1015 | FindBugs: 7 occurrences of "Bad attempt to compute absolute value of signed 32-bit hashcode". In extreme cases, this could lead to SQL syntax errors |
#1016 | The Oracle CONNECT BY cond1 AND cond2 syntax erroneously creates a WHERE cond2 CONNECT BY cond1 statement |
#1028 | Syntax errors when using untyped param() in HSQLDB (and other strongly typed dialects) |
#1029 | Postgres can't bind NULL values in cases, where bind type is Object.class and bind value was created with Factory.param() |
#1030 | UnsupportedOperationException when calling Query.bind(int, Object) on a query containing plain SQL fields |
#1031 | Incorrect debug logging when plain SQL QueryParts like field("?") bind null values |
#1032 | Incorrect debug logging when plain SQL QueryParts contain String literals, such as 'Hello? Anyobody out there?' |
#1047 | Field.notEqualAny() erroneously renders <> ALL() |
Test cases
#1021 | Add explicit integration tests for LEFT|RIGHT|FULL OUTER JOIN |
Version 2.0.1 - December 23, 2011
This is a maintenance release for jOOQ 2.0. The main improvements include
- Better integration for using jOOQ with Spring Data. This includes support for named parameters, as well as allowing to change bind values on previously constructed Query objects
- The MERGE statement has been enhanced for better integration with Oracle.
- jOOQ is now ready to use with Scala / Groovy
For more information about using jOOQ with Scala, see this blog post: https://blog.jooq.org/the-ultimate-sql-dsl-jooq-in-scala/
There is now also experimental support for a custom type mapping. This mapping allows to rewrite data types at code generation time as well as to specify custom enum data types (e.g. boolean Y/N). Not all integration tests run smoothly for custom data types, hence, this feature is not yet fully supported.
Features and improvements
#691 | Add support for Oracle CURSOR REF IN / INOUT parameters |
#677 | Add type-mapping configuration, enforcing types for columns |
#947 | Add custom type mapping support (experimental) |
#968 | Allow for custom enum types, configured in the code generator (experimental) |
#974 | Add Schema.getTable(String), getSequence(String), getUDT(String) for better runtime Schema meta-navigation |
#975 | Add Sequence.getName(), getSchema(), getDataType() |
#980 | Add support for named parameters, to better interact with Spring |
#991 | Add Query.bind(String, Object) and bind(int, Object) to easily modify existing bind values |
#992 | Document thrown DataTypeException in Convert methods |
#998 | Enhance MERGE statement for Oracle extensions: WHEN MATCHED THEN UPDATE .. WHERE .. DELETE WHERE .. WHEN NOT MATCHED THEN INSERT .. WHERE .. |
#1000 | Add support for MySQL's INSERT INTO .. SET .. syntax in MERGE statement's WHEN NOT MATCHED THEN INSERT clause |
API changes (backwards-compatible)
#981 | Cannot insertInto(table("my_table")), as plain SQL tables return Table<Record>, not Table<TableRecord>. Relax bound on R |
#988 | Change Factory.field(String) to return Field<Object> instead of Field<?> |
#999 | Make MERGE's WHEN MATCHED .. and WHEN NOT MATCHED .. clauses optional |
#1001 | Identity.getField() should return TableField<R, T> instead of Field<T> |
#1006 | Add Factory.value(...) as a synonym for Factory.val(...) for increased Scala / Groovy compatibility |
Bug fixes
#973 | EnumType renders name() instead of getLiteral() in formatXXX() methods |
#977 | EnumType renders name() instead of getLiteral() in Convert.convert() method |
#979 | Record.from() sets all changed flags to true. That's not necessarily correct in the event of storing the record back to the DB |
#985 | AbstractRecord.equals() does not correctly compare arrays. Compare them using Arrays.asList() |
#986 | Postgres / DB2 / Sybase ASE foreign-key namespace is unique-per-table. jOOQ forces all foreign keys from all tables into the same namespace |
#990 | Problems when encoding arbitrary byte[] as String(byte[]) in inlined SQL. This can cause issues when DEBUG-level logging is activated |
#995 | Routines don't respect SchemaMapping - Github issue #8 |
#1002 | TableRecord.storeUsing() doesn't update IDENTITY column values, if the column is not part of the main unique key |
#1003 | Sybase / SQL Server / MySQL / Ingres / H2 / Derby's INSERT .. RETURNING simulation returns null if a table has an IDENTITY column, but no primary/unique key |
#1005 | The INSERT INTO .. VALUES .. syntax may cause type-safety issues in some databases. VALUES should be converted before binding |
Test cases
#984 | Detach IDENTITY column tests from UNIQUE KEY tests, create a dedicated test suite instead |
Version 2.0.0 - November 25, 2011
This release is a fresh start in many areas of jOOQ, adressing issues that have been requested by users for a long time. These release notes docment the most important changes, a detailed upgrade guide, as well as the detailed list of improvements.Most important changes
- The API became more static. This applies to many Factory methods, such as val(), literal(), as well as to many Field methods that have been moved over to the Factory. For example, when before, you wrote this using "postfix function notation":
NAME.replace(" ", "_").trim()
you will now write (just as in SQL):
trim(replace(NAME, " ", "_"))
Using static imports of Factory.*, jOOQ makes SQL look even more like SQL. The current "postfix notation" is maintained for backwards compatibility.
- By default, jooq-codegen will now generate a "dynamic" meta model as opposed to the existing static one. Generated tables covariantly override the as(String) aliasing method, leading to a much more convenient aliasing style. When before, you wrote:
Table<TRecord> parent = T.as("parent"); Table<TRecord> child = T.as("child"); Condition join = parent.getField("ID").equal(child.getField("PARENT_ID"))
You can now write:
T parent = T.as("parent"); T child = T.as("child"); Condition join = parent.ID.equal(child.PARENT_ID)
Of course, the existing notation still works
- Exceptions are no longer checked. When previously, the DB's SQLException was propagated to client code, there is now an unchecked DataAccessException hierarchy, similar to that of Spring. This will eventually give way to a standardised error handling abstraction, in future developments.
- Window functions are now constructed from their underlying aggregate functions just like in SQL. For example:
sum(AMOUNT) sum(AMOUNT).over().partitionBy(ACCOUNT)
This makes for a more concise API, especially when considering future extensions, such as Oracle's KEEP (DENSE_RANK FIRST...) syntax.
- More type safety has been introduced regarding various places where generic <R extends Record> and <T> types are involved. This is especially true for INSERT / UPDATE / DELETE statements
- Sequences now also have a <T> type
- Unsigned number types are now supported in those databases that use them. Unsigned numbers are implemented in jOOU, a spin-off open source project. For convenience, this library is "internalised" into jOOQ, to avoid adding a dependency
http://code.google.com/p/joou/
Upgrade instructions:
Various of the above changes are incompatible with jOOQ 1.x. In order to upgrade, please be aware of the following pitfalls:- The schema needs to be re-generated.
- Much of the post-fix function notation is replaced by static methods in the Factory. Today's org.jooq.Field API is maintained in jOOQ 2.0, for backwards compatibility. It will be removed, eventually, though. Expect some incompatible changes, where window functions are involved
- Some Factory instance methods (such as val(), literal()) are now static. They are compatible, but may cause compiler warnings.
- The meta model is now an instance model by default. If you prefer the static meta model, you can configure this in your jooq-codegen configuration.
- The additional typesafety involving <R> and <T> types may cause compiler warnings and errors.
- SQLException is no longer part of the API. This can cause compiler issues, in particular when extending jOOQ
- Some utility classes have moved to org.jooq.tools
Should these incompatibilities be too significant for your project, you can still stay on the 1.x branch, which will be maintained for a while. Be aware that upgrading might be more difficult, later, though.
Features and improvements
#55 | Implement improved exception handling |
#117 | Improve DSL support for field and table aliasing (decrease verbosity) |
#519 | Add support for MySQL UNSIGNED numeric types |
#626 | Create static function access |
#661 | Add support for bitwise operators |
#718 | Sequences should be mapped to appropriate type (e.g. SMALLINT, INT, BIGINT, etc) |
#734 | Add support for Oracle / SQL Server CUBE() and ROLLUP() grouping functions |
#751 | Add support for Oracle / SQL Server GROUPING SETS() function |
#799 | Add support for Oracle PL/SQL's object-oriented MEMBER PROCEDURES and MEMBER FUNCTIONS |
#804 | Add <R extends Record> to Insert, Update, Delete |
#835 | Review API typesafety for <T> InsertSetMoreStep set(Field<T>, T) and similar methods |
#890 | Add Factory.selectCount() convenience method |
#891 | Let min() max(), etc functions return a new type AggregateFunction. This type can then be used as an entry- point for window functions |
#892 | Add support for Oracle / SQL Server GROUPING() and GROUPING_ID() functions to be used along with CUBE() and ROLLUP() |
#893 | Simulate ROLLUP() function for MySQL, using the WITH ROLLUP grouping modifier |
#894 | Move functions from Field<?> to org.jooq.impl.Factory and make them static |
#895 | Add power(..., Field<? extends Number>) |
#897 | Add (experimental) Spring integration project |
#898 | Replace usage of checked SQLException by an unchecked DataAccessException, similar to that of Spring |
#899 | Build jOOQ .jar files as bundles to be deployed into OSGI environments |
#900 | Purge deprecated API - Prior to 2.0 |
#901 | Introduce InvalidResultException as a subtype of DataAccessException for integrity checks in methods like ResultQuery#fetchOne(), ResultQuery#fetchMap(), etc. |
#902 | Make AggregateFunction the base type for constructing window functions |
#904 | Move SQLDialectNotSupportedException into org.jooq.exception package |
#905 | Introduce MappingException as a subtype of DataAccessException for integrity checks in methods like ResultQuery#fetchInto(), etc. |
#907 | Add missing Field.like(Field<T>), notLike(Field<T>) methods to overload the existing Field.like(T), notLike(T) |
#908 | Change rpad / lpad functions to accept String instead of char |
#912 | Add <R extends Record> R newRecord(Table<R>, Object) as the inverse of various into(Class<?>) methods |
#916 | Add <R extends TableRecord<R>> {Record.into(Table<R>) | Result.into(Table<R>) | ResultQuery.fetchInto(Table<R>) | Cursor.fetchInto(Table<R>)} |
#917 | Add various Cursor.fetchOneInto() convenience methods |
#918 | Add CustomTable, CustomRecord as base classes for more convenience when used with various into(Table) methods |
#919 | Allow for accessing non-public constructors of Record subtypes |
#923 | Move some utilities to org.jooq.tools |
#924 | Generate a reference to every table in a new Tables.java class for improved static access |
#928 | Add DataTypeException extending DataAccessException in case something went wrong when converting data types |
#930 | Support converting date time types to java.util.Calendar. This applies to various into(Class<?>) methods, as well as Result.getValue(xx, Class<?>) |
#931 | Allow for conversion between Long and date/time types, and vice versa |
#932 | Let the bound of R in TableRecord extend TableRecord<R>, in UpdatableRecord to extend UpdatableRecord<R> |
#933 | Add support for type Character in Record.into(Class<?>) methods and similar |
#936 | Accept primitive types, such as int.class for type conversion |
#938 | CODEGEN: Add static/instance table field configuration |
#939 | Include license.txt and readme.txt in .jar files' META-INF directory |
#953 | Make DefaultGeneratorStrategy methods non-final to allow for overriding |
#954 | Add examples for source code generation of multiple schemata with Maven |
#955 | Generate a reference to every type in a new UDTs.java class |
#957 | Add <R> R Factory.newRecord(UDT<R>) for constructing attached UDTRecords |
#958 | CODEGEN: Add generation-time schema mapping, allowing for re-writing schemata in jooq-codegen |
#960 | CODEGEN: Add code generation configuration parameter to avoid using the new UByte, UShort, UInteger, ULong wrappers for UNSIGNED number types |
#961 | Use Oracle's SYS.ALL_SEQUENCES.MAX_VALUE to determine the type of a sequence. |
#969 | Add <T> List<T> ResultQuery.fetch(Field<?>, Class<? extends T>) convenience method |
Bug fixes
#686 | Reduce the internal API leak by preventing access to TableFieldImpl, UDTFieldImpl, ParameterImpl |
#903 | lag(Field, int, T) erroneously delegates to lead() |
#906 | Add more NullPointerException safety to API |
#913 | NoClassDefFoundError in JooqUtil.isJPAAvailable() |
#920 | Generic type is lost in Cursor.fetchInto(RecordHandler) |
#925 | SelectConditionStep should extend SelectConnectByStep, not SelectGroupByStep |
#926 | AbstractRecord.into() fails to convert java.sql.Date into java.util.Date |
#934 | Don't consider static members in reflection utilities when used with Record.into(Class<?>) and similar methods |
#935 | Don't consider final member fields in reflection utilities when used with Record.into(Class<?>) and similar methods |
#937 | In the event of name clash (same name for table and field) generated code has errors |
#945 | Calling UpdatableRecord.setValue() twice with the same argument causes the changed flag to be reset to false |
#948 | Always set the changed flag to true in Record.setValue() |
#959 | Compilation errors in generated source code if MySQL enum values match Java reserved words, such as 'true', 'false', 'new', etc... |
#962 | Postgres ordering of generated enum literals is unstable |
#967 | Better document type conversion |
Version 1.7.0 - November 25, 2011
This is a maintenance release for the 1.x branch. Some important bug fixes are merged from version 2.0. These include:Bug fixes
#925 | SelectConditionStep should extend SelectConnectByStep, not SelectGroupByStep |
#926 | AbstractRecord.into() fails to convert java.sql.Date into java.util.Date |
#937 | In the event of name clash (same name for table and field) generated code has errors |
#945 | Calling UpdatableRecord.setValue() twice with the same argument causes the changed flag to be reset to false |
#948 | Always set the changed flag to true in Record.setValue() |
#951 | Empty Password for jooq-codegen-maven causes NPE |
Version 1.6.9 - November 7, 2011
This is a maintenance release for the 1.x branch. Developments on this branch will stop after version 1.6.9. Only important bug fixes are merged to this branch. Developments for release 2.0 have started.The most important functionality in release 1.6.9 is the newly added support for JDBC batch operations. You can now batch execute several queries.
See the official blog for more information: https://blog.jooq.org/jdbc-batch-operations-with-jooq/
Features and improvements
#621 | Add support for JDBC batch operations |
#794 | Add support for ORDER BY [int value] in order to reference a column index for sorting |
#882 | Optimise Field.isTrue() and isFalse(). Take Field's data type into consideration. |
#885 | Add support for INSERT INTO .. VALUES (..) syntax, omitting explicit field declarations |
#887 | Add <E> List<E> Cursor.fetchInto(Class<E>) |
Bug fixes
#748 | H2 regression in 1.3.158 regarding stored functions, which return a ResultSet (this was fixed in H2) |
#859 | Derby casting of numeric types to BOOLEAN doesn't work |
#886 | Regression in date extract function when used in a subselect |
#888 | Derby casting of VARCHAR to FLOAT (and similar) doesn't work |
Version 1.6.8 - October 22, 2011
The main improvement of this release is the re-design of the stored procedure / function API. With 12 supported RDBMS, which all have their own idea about what is a stored procedure and what is a stored function, it has proven to be a better design, to unite them in one single type: org.jooq.Routine. A routine can have a return value as well as OUT parameters. It can be embedded in SQL and used as a field or a table.This means, you will need to re-generate your database schema, when upgrading to jOOQ 1.6.8. After re-generation, you'll need to fix your client code. These are the package changes:
- [generated.package].procedures > [generated.package].routines
- [generated.package].functions > [generated.package].routines
- [generated.package].Procedures > [generated.package].Routines
- [generated.package].Functions > [generated.package].Routines
Oracle generated packages are not re-located. With these improvements, using stored procedures and functions becomes even more reliable, especially when cursor types are involved. Read more about the rationale behind this change:
https://blog.jooq.org/what-are-procedures-and-functions-after-all/
Apart from that, important improvements have been made in the area of plain SQL tables. Also, consider a demo integration of jOOQ with Google Cloud SQL:
https://blog.jooq.org/jooq-and-google-cloud-sql-example/
Features and improvements
#271 | Don't pre-fetch table meta data when selecting from plain SQL tables |
#489 | Add support for SELECT * (i.e. render SELECT * where applicable) |
#596 | Add support for VARIANCE() and STDDEV() OVER() window functions |
#608 | Add jOOQ version number in generated source code |
#670 | Add more Javadoc to Field.xxx() functions |
#692 | Add support for ResultSet type returned from HSQLDB stored functions |
#850 | Use https://www.jooq.org as URL for the @Generated annotation |
#854 | Add convenience methods Fields.isTrue(), isFalse() for conversion of "Y", "YES", "1", "true", "on", etc into a boolean condition |
#870 | Add support for MEDIAN aggregate function |
#872 | Add support for STDDEV_POP(), STDDEV_SAMP(), VAR_POP(), VAR_SAMP() aggregate functions |
#874 | Reduce the number of internal classes for dialect-specific function aliases |
#878 | Implement DataType.equals() and hashCode() |
API changes (backwards-compatible)
#851 | Change Field.{sortAsc|sortDesc}(List<T> sortList) into Field.{sortAsc|sortDesc}(Collection<T> sortList) |
API changes (backwards-incompatible)
#848 | Purge deprecated API - Prior to 1.6.1 |
#849 | Replace Cursor.fetchResult() by Cursor.fetch() |
#852 | Review stored procedures / functions concept. Merge them all into a single "Routine" type |
Bug fixes
#756 | Error when aliasing HSQLDB and Postgres unnested tables |
#761 | Exception when TRACE logging execution with plain SQL tables involved |
#773 | Execute standalone stored functions as CallableStatement to prevent issues with transactions |
#847 | Query.getSQL() doesn't render dialect-specific SQL when Query is constructed using the fluent API |
#853 | DB2 generated convenience methods for stored functions have unstable ordering |
#857 | Derby casting of numeric types to String / VARCHAR does not work |
#858 | SQLDataType.getSQLDataType() should return itself, instead of null |
#860 | SQLite CEIL function is incorrectly simulated. CEIL(2.0) returns 3.0 instead of 2.0 |
#861 | Field.replace(String) generates bad SQL for various RDBMS. Field.replace(String, String) works, though |
#863 | Ingres integration generates illegal SQL when selecting things like SELECT 1 WHERE 1 = 1 |
#866 | Sybase ASE Field.replace(String) function incorrectly removes the argument string |
#873 | Error when selecting two times the same aggregate field |
#877 | Compilation error in generated source code when a table without a primary key has an identity column |
#879 | Add Google Cloud SQL Example |
#880 | Query.getSQL() does not consider SchemaMapping |
Test cases
#811 | Loader integration tests fail for SQLite |
#812 | CSV Loader test leaves Postgres JDBC connection in an inconsistent transactional state on error |
#856 | Add integration tests for Field.abs() |
#865 | Add integration tests for Field.ascii() |
#867 | Add integration tests for Field.sum(), avg(), max(), min() |
#881 | Re-design H2 stored functions to be pre-compiled, in order to speed up integration tests |
Version 1.6.7 - September 25, 2011
This release coincides with the launch of the new website at https://www.jooq.org. Hence, it ships with little additions to the deliverable itself.
Apart from new convenience methods, the main addition is a Maven plugin for jooq-codegen contributed by Sander Plas.
Features and improvements
#797 | Create Maven plugin for source code generation |
#825 | Add List<Result<Record>> Factory.fetchMany(String) to allow for fetching several result sets from stored procedures, such as Sybase ASE's "sp_help" |
#838 | Implement MetaDataFieldProvider.toString() |
#841 | Add <T> List<T> Result.getValues(Field<?>, Class<T>) |
#842 | Add Query.getBindValues() method to allow for extracting bind values in the correct order |
#843 | Add Factory.fetch(ResultSet) to transform a JDBC ResultSet into a jOOQ Result |
API changes (backwards-compatible)
#837 | Avoid final keyword on Object methods, such as .equals(), .hashCode(), etc |
Bug fixes
#836 | Bad syntax when selecting from aliased plain SQL tables |
#839 | Boolean conversion in getValueAsBoolean() should trim String values first |
#840 | Numeric conversions in getValueAsXXX() should trim String values first |
#844 | NullPointerException when selecting a column from a Result, that does not exist |
Version 1.6.6 - September 11, 2011
Finally, support for another RDBMS has been added. Sybase's other important product Sybase Adaptive Server Enterprise (or simply Sybase ASE) is now officially supported by jOOQ
Apart from this, there had been important improvements with the recently added INSERT .. RETURNING clause, as well as some fixes related to DECIMAL / NUMERIC data types
Features and improvements
#796 | Complete missing public org.jooq.impl Javadoc |
#800 | Add support for Sybase Adaptive Server Enterprise |
#808 | Add support for INSERT .. RETURNING for Ingres |
#809 | Add support for INSERT .. RETURNING for Sybase SQL Anywhere using SELECT @@identity |
#810 | Add support for INSERT .. RETURNING for SQLite using last_inserted_rowid() |
#813 | Add DSL support for INSERT .. RETURNING |
#814 | Change TableRecord to reload its trigger-initialised main key in Oracle and other RDBMS that don't support IDENTITY columns |
#818 | Add SQLiteFactory.rowid() |
#819 | Support SQLite AUTOINCREMENT columns as IDENTITY |
#820 | Add Factory.fetchOne(String) for executing plain SQL queries that return single records |
#826 | Allow for returning several records in the INSERT .. RETURNING clause. This now works for DB2, HSQLDB, MySQL, and Postgres |
#827 | Support Sybase SQL Anywhere's TOP n START AT m clause instead of simulating it with nested SELECT's |
API changes (previous API now deprecated)
#817 | Deprecate Factory.lastID(Identity) |
Bug fixes
#815 | SQL Server fetching of IDENTITY value is broken |
#821 | Optimise ResultQuery.fetchAny() executing fetchLazy() internally, and only fetching one record from the cursor |
#822 | Let Constant cast to more precise NUMERIC/DECIMAL types in those RDBMS where casting is necessary |
#823 | Cannot bind SQLite BigDecimal, BigInteger types - bind them as String instead |
#824 | BigInteger values cannot be bound in DB2, Derby |
#828 | Document inefficient implementation for GREATEST and LEAST in some RDBMS |
Version 1.6.5 - August 28, 2011
This release finally adds a loader for CSV data to jOOQ. You can now load CSV data using a simple fluent API, configuring error handling, duplicate behaviour and transaction handling, as well as various CSV parameters.
This release also changes the way generated keys are retrieved after INSERT's. Instead of (potentially inconsistently) running SELECT MAX(pk) immediately after the INSERT, Postgres' INSERT.. RETURNING clause is used (or simulated), in a single statement.
Features and improvements
#784 | Add Result.exportXML() to retrieve a DOM document similar to that of .formatXML() |
#792 | Add support for loading of CSV data into tables |
#795 | Add <T> List<T> fetch(int, Class<T>) and fetch(String, Class<T>) convenience methods |
#803 | Add support for INSERT .. RETURNING or simulate it where not available |
#805 | Add <T> T[] fetchArray(int, Class<T>) and fetchArray(String, Class<T>) convenience methods |
#806 | Add <T> T fetchOne(int, Class<T>) and fetchOne(String, Class<T>) convenience methods |
Bug fixes
#798 | Oracle IN (...) clause with more than 1000 arguments does not work |
#802 | Use "INSERT .. RETURNING" instead of "SELECT MAX(pk)" to retrieve the primary key of a new record |
Version 1.6.4 - August 07, 2011
This release ships with a couple of useful concepts inspired by other frameworks. These are:
- selecting into custom POJO's. Results can be mapped to POJO's by convention or using JPA @Column annotations
- selecting into custom callbacks. This is already a wide-spread practice in Spring JdbcTemplates.
- selecting long-running queries asynchronously. This idea has been inspired by the Avaje Ebean framework
Apart from these changes and some bugfixes, the internal API has been completely re-designed. The idea here is that query rendering and variable binding are even faster (less String objects), more extensible and more accurate. This is a pre- requisite for many future developments with even more complex SQL statements, such as for instance CTE's (Common Table Expressions)
Features and improvements
#137 | Add support for asynchronous query execution using FutureResult<R> ResultQuery.fetchLater() similar to Avaje Ebean |
#198 | Add SELECT INTO functionality into POJO's using <T> T ResultQuery.fetchInto(Class<T>) similar to JPA CriteriaQuery |
#728 | Add .fetchInto(RecordHandler<R>) to ResultQuery, Result, and Cursor to allow for callbacks similar to Spring's JdbcTemplate/Ollin Framework |
#774 | Add more TRACE logging to .fetchLazy() |
#777 | CURSOR: Add function alias: UNNEST for TABLE |
#781 | Add E function (Euler number) |
#782 | Add <T> T Record.getValue(..., Class<? extends T>) methods for convenient type conversion |
#785 | Allow for storing TableRecord with a provided Field<?>[] indicating the primary key |
#786 | Document thread-safety facts in Factory Javadoc |
#788 | Add Key.getFieldsArray() convenience method |
#793 | Add support for Oracle's SYS_CONNECT_BY_PATH function |
API changes (backwards-incompatible)
#758 | Change internal QueryPart rendering and binding API to use Configuration and Context as callback parameters. If you use CustomField or CustomCondition, please correct your implementations accordingly. Other parts of the API should not be affected |
#778 | Purge deprecated API, deprecation prior to jOOQ 1.5.7 |
#790 | Purge deprecated generated code, deprecation prior to jOOQ 1.5.7 |
API changes (previous API now deprecated)
#776 | Deprecate QueryPart.getSQL(), add Query.getSQL() |
#789 | Deprecate Record constructors with Configuration parameter |
Test cases
#636 | Add integration tests for more advanced CONNECT BY example |
#772 | Add integration tests for selecting cartesian products (several tables in FROM clause) |
Bug fixes
#730 | Sybase cannot bind null values in plain SQL |
#759 | Omit the TOP 100 PERCENT clause in SQL Server ordered top-level queries |
#767 | An empty Java package is generated for PL/SQL packages containing underscores |
#771 | Some exotic literals are not properly escaped with quotes yet, e.g. UDT identifiers, VARRAY types, etc. |
#775 | Automatic re-attaching after deserialisation does not work when used with .fetchLazy() |
#787 | The UpdatableRecord's internal changed flags are not updated after INSERTs / UPDATEs |
Version 1.6.3 - July 31, 2011
This is mainly a maintenance release with lots of bugfixes, mostly around code generation, plain SQL tables, and data types. Please note that generated source code may contain incompatible changes due to #639 (see below for details)!
Apart from that, project CURSOR is advancing and it is now possible to unnest arrays into tables. See this article for details about where jOOQ is heading with project CURSOR:
https://blog.jooq.org/the-power-of-ref-cursor-types/
Features and improvements
#679 | Improve H2 NVL2 support as of H2 1.3.156 |
#680 | Improve H2 ROUND support as of H2 1.3.156 |
#735 | Add README documentation to GitHub |
#736 | Add more info regarding number of generated artefacts in jooq-codegen logging |
#750 | Add DataType.isNumeric(), .isString(), .isTemporal(), .isBinary() |
#754 | Log query as executed by JDBC PreparedStatement when TRACE logging (without inlining variables) |
#752 | CURSOR: Add support for selecting from ARRAY types |
#762 | Use H2's native support of NVL, instead of COALESCE |
#764 | CURSOR: Add support for selecting from ARRAY types returned from stored functions |
API changes (backwards-incompatible)
#639 | Map DECIMAL(n, 0) and NUMBER/NUMERIC(n, 0) data types to Byte/Short/Integer/Long/BigInteger instead of BigDecimal in generated source code. Re-generated code will not be compatible! |
API changes (previous API now deprecated)
#731 | Inconsistent API with Field.lessOrEqualToXXX(). Removed "To" from method name |
#757 | Deprecate Factory.constant() methods |
Test cases
#731 | Add missing integration tests for equalAll(), equalSome() and similar methods |
#747 | Upgrade H2 to 1.3.158 |
Bug fixes
#632 | Sybase error : column @p0 not found in nested SELECT |
#700 | Restore HSQLDB ARRAY support with INFORMATION_SCHEMA change in HSQLDB 2.2.3, and some fixes in 2.2.5 |
#725 | Cannot insert byte[] data with plain SQL |
#733 | H2 changed JDBC type for ResultSet/CURSOR from 0 to -10, like Oracle |
#737 | Compilation errors in generated source code if table fields contain spaces |
#738 | Compilation errors in generated source code if MySQL procedure parameter type contains two comma-separated arguments (like DECIMAL(10,2)) |
#739 | Postgres navigator methods and keys are not re-generated in the same order |
#740 | Formatting is broken on Result.format() with some special newline characters |
#743 | Make SQL Server INFORMATION_SCHEMA independent from HSQLDB again, to prevent incompatibility issues |
#744 | Ingres REAL and FLOAT4 types are generated as FLOAT/FLOAT8 which maps to java.lang.Double, instead of java.lang.Float |
#753 | Postgres error when binding array that contains null values |
#755 | NullPointerException when converting an array containing a null value |
#766 | Bad decoding of JDBC Types BIGINT (to BigInteger instead of Long) and REAL (to BigDecimal instead of Float) when plain SQL tables are involved |
Version 1.6.2 - July 10, 2011
This release mainly introduces three new projects.
Project CURSOR where jOOQ finally supports various RDBMS's TABLE, CURSOR, and REF CURSOR data types. This is especially useful when those types are returned from stored procedures and functions. Cursors are simply mapped to jOOQ Result<Record> types and can thus be used like regular table results
Project EXPORT aims at exporting data from the database in various serialisable formats, such as XML, CSV, HTML, Text, JSON. This project will be continued in the future, to also deserialise from (some of) these data streams. This will allow for easy transport of jOOQ Result<?> types over the net.
Project CODEGEN has finally been started. Many improvements suggested by jOOQ users will be implemented in the next releases. In this release, important fixes have been made to prevent compilation errors in generated artefacts.
Features and improvements
#61 | EXPORT: Add Result.formatXML() |
#166 | CURSOR: Add support for ResultSet type returned from Oracle stored procedures / functions |
#411 | Allow for fetching Map<String, Object> (instead of Record) and List<Map<String, Object>> (instead of Result) |
#549 | Add Factory.function() for plain SQL functions |
#611 | Simulate RPAD and LPAD in SQL Server, Sybase |
#627 | Add support for Postgres FOR UPDATE OF [table-name] clause |
#628 | Add support for REPEAT (SQL Server: REPLICATE) function |
#637 | Nicely format time in StopWatch logging output |
#640 | Simulate Postgres FOR UPDATE OF [table-name] clause in other dialects |
#649 | CURSOR: Add Cursor.fetch(int) .fetchOne() .fetchResult(int) .fetchResult() |
#653 | Add support for MySQL encryption and compression functions |
#660 | Clarify Javadoc of UpdatableRecord to explain its behaviour when changing the main unique key |
#669 | EXPORT: Add Result.formatHTML() |
#672 | Add convenience method UpdatableRecord.copy() in order to reset primary key values for a subsequent INSERT |
#675 | EXPORT: Add Result.formatCSV() |
#683 | Implement ResultImpl.equals() and .hashCode() |
#684 | Implement AbstractStore.equals() and .hashCode() |
#685 | Add Store.size() to indicate the maximum index of the Store |
#687 | EXPORT: Add result.formatJSON() |
#689 | Create separate builds: jooq-core.zip and jooq-with-dependencies.zip |
#690 | CURSOR: Add support for ResultSet type returned from H2 stored functions |
#695 | CURSOR: Add support for ResultSet type returned from Postgres stored functions |
#697 | Add Factory.fetch(String) for executing plain SQL queries that return results |
#701 | Add ResultQuery.fetchArray() and .fetchOneArray to return Object[][] and Object[] |
#704 | Always add top and bottom line in Result.format() |
#705 | Right-align numeric values in Result.format() |
#716 | Add SUBSTRING function Field.substring(Field, Field) taking fields as arguments |
#719 | Document risk of SQL injection in plain SQL and literal factory methods |
#726 | Add LENGTH function as a synonym for CHAR_LENGTH |
API changes (backwards-compatible)
#698 | Inconsistent API with Factory.fetch(Table<R> [,Condition]) Let method return Result<R> instead of List<R> |
#699 | Let Result<R extends Record> extend List<R> |
API changes (previous API now deprecated)
#656 | Decrease verbosity of plain SQL methods. They will just be called Factory.field() .condition() .table() .query() |
Test cases
#643 | Add integration test for code generation of invalid and incomplete types in Oracle |
#654 | Add integration tests for master data tables with PK types other than NUMBER/INT |
#655 | Add missing integration tests for TRIM function |
Bug fixes
#450 | Improve plain SQL integrity checks for bind variables |
#610 | CODEGEN: Compilation error in generated source code for databases with table named 'system' |
#646 | An empty Java package is generated for an empty PL/SQL package. This is unnecessary |
#651 | CODEGEN: Avoid importing datatypes in generated source code to prevent collisions |
#657 | NullPointerException when creating a Factory with a null SchemaMapping |
#658 | Master data table code generation is broken for tables with more or less than 3 columns |
#662 | Add support for the missing Postgres data type "bpchar" |
#663 | Add support for the missing Sybase data type "int" |
#664 | Ingres INTEGER data types are not correctly generated |
#665 | HSQLDB Datatype CLOB and BLOB are not supported, when selecting from plain SQL tables |
#666 | The evil bug: Ingres TRIM function only executes RTRIM |
#673 | UpdatableRecord.store() doesn't work if called after .delete() |
#702 | Add support for the missing SQLite data type "NULL" |
#706 | CURSOR: Ensure that Query.execute() runs in a single transaction when Postgres refcursor is involved in the query (this fixes a Postgres JDBC driver flaw) |
#724 | NullPointerException when passing a single literal null bind value to plain SQL methods without casting to Object |
#729 | DB2, Derby, Ingres, Oracle cannot bind null values in plain SQL |
Version 1.6.1 - June 19, 2011
In this release, the PORTABILITY project has been implemented. Finally, the SQLDialect has been removed from most generated artefacts (Schema, Table, Field, Sequence, etc). Also, the constructing Factory is not referenced by its created QueryParts anymore, unless this is really necessary (Query objects, UDT's, ARRAY types). This leads to higher compatibility between schemata of different databases, e.g. if users want to use an HSQLDB development and Oracle productive database.
Unfortunately, this means that the way stored procedures are called had to be changed. This is an API break that could not be avoided. The pre-1.6.1 StoredObject.execute(Connection) method is deprecated and will be removed in the future. It has been replaced by StoredObject.execute(Configuration)
In addition to this project, many more window functions are now supported, as well as the Oracle-specific CONNECT BY clause for recursive queries.
Features
#351 | Add support for Oracle ROWID data type |
#452 | PORTABILITY: Create a super-set of RDBMS data types |
#453 | PORTABILITY: Don't create dialect-specific QueryParts |
#455 | Add support for the Oracle CONNECT BY clause |
#587 | Add optional OFFSET clause to form LIMIT .. OFFSET constructs |
#589 | Add extended FOR UDPATE [OF ...] [{WAIT n | NOWAIT | SKIP LOCKED }] support |
#591 | Add support for LEAD() OVER() and LAG() OVER() window functions |
#592 | Add support for the CUME_DIST() OVER() window function |
#601 | Add Factory.literal() convenience methods |
#602 | Add Factory.val() methods to decrease .constant() verbosity |
#604 | Add support for RESPECT NULLS clause in some window functions |
#605 | Add Factory.use(String) for non-generated schemata |
#613 | Add PI function |
#616 | Add Factory.two() literal convenience method |
#630 | Add support for Oracle CONNECT BY pseudo-columns LEVEL, CONNECT_BY_ISCYCLE, CONNECT_BY_ISLEAF |
API changes
#299 | PORTABILITY: Create a dialect-independent meta-model |
#588 | Add OVER() keyword to FIRST_VALUE() and LAST_VALUE() API |
Test cases
#368 | Add integration test for use with schema mapping |
#586 | Upgrade H2 to 1.3.155 |
#607 | Add integration tests for CRUD / SP's / UDT's / ARRAY's with SchemaMapping |
#612 | Add integration tests for LPAD and RPAD functions |
#624 | Add integration test for code generation of invalid/ incomplete views in Oracle |
#631 | PORTABILITY: Add integration tests for using Oracle- generated schema against an HSQLDB database |
#638 | Add missing integration test for DECIMAL data type |
Bugfixes
#176 | Stored procedures / functions in EQUIVALENT schemata cannot be called |
#493 | Bind variable mismatch when constructing bad SQL |
#594 | Confusing Javadoc in SELECT DSL API |
#603 | Fix DB2 'IGNORE NULLS' clause |
#619 | SUBSTRING() function is broken in DB2, Ingres, SQL Server |
#623 | SQL syntax error for some MERGE queries in SQL Server and Sybase |
#633 | SchemaMapping is not applied to sequences |
#634 | Sequences are not escaped in generated SQL |
Version 1.6.0 - June 05, 2011
Apart from supporting various additional standard and non- standard JOIN constructs, there is now also full support for the SQL standard MERGE statement and MySQL's ON DUPLICATE KEY variant thereof. A great number of API enhancements have been added, which improve the usability of jOOQ. The Ingres database is now also supported.
Features
#301 | Add support for Oracle execution hints |
#409 | Add support for NATURAL JOIN syntax, where RDBMS allows it |
#415 | Make fluent API's underlying SelectQuery objects publicly available |
#429 | Add Ingres support |
#475 | Document class-level generic types <R> and <T> in Javadoc |
#486 | Add support for SQL MERGE clause |
#494 | Allow for omitting schema name in generated SQL |
#496 | Automatically update IDENTITY values in UpdatableRecord, after storing them |
#520 | Add support for JOIN ... USING syntax |
#524 | Upgrade HSQLDB to 2.2 |
#533 | Add ORDER BY [Map] or BY [List] functionality |
#534 | Add Result.isEmpty() |
#535 | Call upon ConfigurationRegistry.provideFor() before throwing a DetachedException |
#536 | Simulate CASE [value] WHEN [value] THEN [result] END syntax in Derby |
#538 | Add some logging to ConfigurationProvider |
#539 | Add possibility to negate numeric values with Field.neg() |
#541 | Add support for MySQL ON DUPLICATE KEY clause |
#542 | Allow for Collection arguments in INSERT's DSL API |
#543 | Allow for creating FUNCTION() OVER() without PARTITION BY or ORDER BY clause |
#546 | Add Factory.use(Schema) |
#548 | Add new internal type FieldMap |
#550 | Simulate ON DUPLICATE KEY INSERT clause in dialects other than MySQL |
#551 | Add TableMapping, similar to SchemaMapping for mapping tables |
#553 | Add Factory.plainSQLQuery |
#554 | Add Factory.plainSQLField with a DataType parameter |
#555 | Add UpdateXXX.set(Map) convenience methods to DSL API |
#557 | Enhance INSERT DSL API to allow for adding VALUES clause with InsertXXX.set() syntax |
#570 | Add support for the RAND() function |
#567 | Add support for Ingres Sequences |
#572 | Add support for the ATAN2() function |
#573 | Add possibility for additional select() clauses for convenience |
#575 | Add support for the FULL OUTER JOIN syntax, where RDBMS supports it |
#576 | Add support for the CROSS JOIN syntax, where RDBMS supports it |
#581 | Enhance API and allow Collection<? extends Field<?>> instead of Collection<Field<?>> |
API changes
#397 | Purge deprecated API |
Bugfixes
#481 | Handle case where an empty record is stored |
#522 | Misleading Javadoc in generated stored procedures and function constructors |
#532 | Restore Postgres INFORMATION_SCHEMA |
#537 | Prevent null from being added to QueryPartList |
#540 | Error when TRACE logging Limit |
#544 | Aliased elements are not bound correctly when rendered with toSQLReference() |
#559 | Loosen type safety on overloaded methods to prevent compilation errors with javac/Netbeans |
#560 | HSQLDB DataType REAL is configured incorrectly |
#565 | Add integration tests for current_user() function |
#569 | ORA-01427 when generating foreign key relations |
#571 | Field.trim() not correctly implemented for SQL Server |
#583 | Accelerate integration tests: Reset schema only if necessary |
Version 1.5.9 - May 15, 2011
This version ships with lots of new functionality. Finally, the DSL-style API has been extended to CRUD operations (INSERT, UPDATE, DELETE)! Also, support for the TRUNCATE TABLE statement has been added.
The most important new features include the support for SQL:2003 standard window functions, which are available in most major RDBMS. Additionally, basic function support has been widely extended.
Features
#148 | Added support for window functions |
#204 | Add support for multi-record INSERT's |
#416 | Added support for retrieval of IDENTITY values |
#433 | Use bind variables for LIMIT and OFFSET |
#441 | Added foreign key relationship meta information to the generated source code |
#446 | Beautify ResultImpl.toString() method |
#461 | Automatically cast CONCAT parameters to Field<String> if necessary |
#463 | Added support for trigonometric functions |
#471 | Added support for the sign function |
#472 | Added support for GREATEST/LEAST functions |
#474 | Added support for "hyperbolic" functions SINH, COSH, TANH, and COTH |
#482 | Added DSL API for INSERT statements |
#483 | Added DSL API for UPDATE statements |
#484 | Added DSL API for DELETE statements |
#485 | Added "Registry" for client code to provide Configurations to jOOQ Attachables |
#490 | Added support for the TRUNCATE TABLE statement |
#495 | Generate source code for IDENTITY columns |
#501 | Added support for boolean conversion to Result, Record, and Store |
#503 | Allow for schema navigation via generated artefacts |
#518 | Let stored procedures reference owner package if applicable |
#525 | Added NULLS {FIRST | LAST} clause to ORDER BY constructs |
#528 | Added Factory.getDataType() convenience method |
#530 | Added Factory.zero() and Factory.one() convenience methods |
API changes (jooq)
#527 | Weakened type-safety on Field.nvl2() |
#529 | Deprecated Factory.select(Object...), added .selectOne() and .selectZero() instead |
API changes (jooq-meta)
#30 | Add ParameterDefinition for stored procedures, instead of reusing ColumnDefinition |
#499 | Add reference to TableDefinition in ColumnDefinition |
#500 | Add AttributeDefinition for UDTDefinition, instead of reusing ColumnDefinition |
Bug fixes
#369 | Adapt H2 relations generation to H2's correction of information_schema.cross_references |
#435 | Added integration tests for NESTED SELECTs holding LIMIT clauses |
#460 | Syntax error when using a field with a reserved name |
#462 | Fixed Javadoc broken links |
#473 | Don't cast when cast is unnecessary |
#479 | INSERT statement should not set all fields for a table |
#497 | Derby referential code generation is broken, for named foreign keys |
#498 | Oracle package content is generated in arbitrary order |
#502 | Syntax error when creating an empty IN condition |
#526 | Corrected Javadoc in Field.coalesce() |
Version 1.5.8 - April 29, 2011
Finally, jOOQ now supports two important new RDBMS: SQL Server and Sybase!
Apart from this great enhancement, there is now also full support for the non-SQL standard LIMIT clause, even in dialects where the LIMIT clause is not supported natively (especially Oracle, but also DB2, SQL Server and Sybase, which have limitations). jOOQ simulates LIMITs by rendering nested selects filtering on ROWNUM (Oracle) or on ROW_NUMBER() (DB2, SQL Server and Sybase).
Other interesting additions are an increasing support for native mathematical functions. More function support will be added in future versions.
Features
#16 | Added support for SQL Server |
#21 | Uniform implementation of the LIMIT clause. Implemented LIMIT clause simulation through analytic functions, where LIMIT is not supported natively |
#97 | Added support for Sybase |
#418 | Measure time of various steps in source code generation |
#420 | Added support for proprietary SQL extensions "FOR UPDATE" and "FOR SHARE" |
#431 | Added additional statistics to generation log files |
#432 | Unified the various "standard" ANSI INFORMATION_SCHEMA implementations in the jooq-meta artefact |
#436 | Added support for the modulo function |
#438 | Added floor and ceil functions |
#439 | Added support for mathematical functions (logarithms, exponentials, sqrt) |
#447 | Enhanced Field.add() and Field.subtract() to work for date time fields, also |
API changes
#428 | Created new Maven artefact jooq-meta to cleanly separate database meta-data navigation from code generation |
#458 | Decreased DSL verbosity for arithmetic operations and for ordering |
Bug fixes
#417 | Restored warning when unknown column type is encountered in source code generation |
#419 | Corrected misleading Select.fetchOne(...) Javadoc |
#421 | Optimised AbstractRecord's memory consumption |
#448 | Corrected some Javadoc @see links |
#449 | Changed Field.concatenate() to accept Field<?> parameters to avoid generic varargs warnings |
Version 1.5.7 - April 17, 2011
This is the first release built with support of Maven thanks to the help of some jOOQ users!
The main new features in this release are the improved support for serialisation/deserialisation of jOOQ objects through use of the newly introduced "Attachable" interface.
If using log4j or the newly supported slf4j logging framework in debug/trace mode, there is the possibility to log query building/execution time statistics.
Apart from these new features, fixes were mainly done in the fields of type casting, HSQLDB 2.1 upgrade support, stored procedures with OUT, IN/OUT parameters. Please upgrade, if you are using any of those features.
If you extend jOOQ as a base implementation for source code generation, be aware of the fact, that the jOOQ-codegen is currently undergoing major changes. Expect the code generation API to stabilise again in one of the next releases.
Features
#104 | Added maven dependency |
#248 | Integrate UDT types with ARRAYs |
#295 | Allow for attaching/detaching UpdatableRecords to/from Configurations |
#359 | Added statistics measurement to Query execution for debug log level |
#362 | Added deprecation configuration flag |
#364 | Document unknown type in generated source code |
#373 | Improve exception handling in code generation |
#378 | Added support for Oracle stored functions with OUT parameters |
#382 | Added Factory.attach() methods to re-attach deserialised Attachables |
#394 | Add logging support for SLF4J |
#398 | Allow to provide a DataType in Factory.constant() |
#399 | Provide access to TypeUtils.convert() methods via DataType |
#404 | Added trace logging for measuring the speed of various query execution steps |
API changes
#358 | Enhanced DSL API to allow for HAVING clauses without GROUP BY clauses |
#367 | Make Store, Result, QueryPart "Attachable" |
#374 | Introduce strategy pattern to code generation for future support for advanced naming schemes |
#375 | Decouple Database from Generator |
#381 | Made DataType Serializable |
#384 | Deprecated singleton QueryParts |
#388 | Unify "internal" API using an Adapter pattern |
Bug fixes
#187 | Protect generated Record navigation methods against name clashes |
#266 | Added more thorough integration tests for dialect-specific casting (including some fixes related to varchar types) |
#360 | Added more integration tests for the DISTINCT clause |
#361 | Add more checks in testInsertUpdateDelete() |
#366 | Warn only once per ColumnDefinition, if a data type is unknown |
#377 | NullPointerException when generating invalid stored function |
#380 | Added integration tests to check for proper serialisability |
#386 | Fixed incompatibilities with HSQLDB 2.1.0 |
#387 | Fixed unnecessary imports in some Oracle generated Records |
#389 | Fixed javac compiler warning in AbstractStoredObject |
#391 | Cannot properly call stored procedures when IN/OUT parameter is bound to NULL |
#392 | Procedures with several OUT parameters may not register OUT parameters correctly |
#410 | Passing null VARRAY values to Oracle stored procedures causes issues |
#412 | limit(int) sets default offset incorrectly in some dialects |
Version 1.5.6 - March 31, 2011
This release consists mainly of code generation bug fixes and minor API improvements and enhancements.
The most important improvement is ticket #90, by which lazy fetching and iteration over data is now supported. jOOQ lets you keep a reference to a Cursor that has an open JDBC ResultSet, to fetch data from on-the-fly.
A few major code generation bugs were reported where the generated code may cause ambiguity due to an inconsistent API. This means that you will have to re-generate your schema after upgrading to version 1.5.6. Some of your code may not compile anymore, after this upgrade.
Features
#90 | Added possibility for lazy fetching of data |
#208 | Added convenience methods for direct invocation of sequences' currval() and nextval() attributes |
#212 | Created one factory per dialect for better separation of dialect-specific support |
#213 | Generate a factory for each schema |
#251 | Opened up base implementations for Field<?> and Condition to allow for custom implementations by client code |
#274 | Integrate H2 ARRAY types with stored procedures |
#292 | Documented usage of log4j and java.util.logging |
#306 | Added support for the NULLIF function |
#319 | Added Field.between(Field<T>, Field<T>) method |
#320 | Added trace logging for variable binding and SQL generation methods |
#323 | Added Field.in(Field<?>...) method |
#325 | Include release version number in delivered .jar files |
#328 | Improved configuration setup documentation page |
#333 | Let Result implement Serializable |
#334 | Added fetchMap() convenience methods |
#335 | Added more functions and aggregate functions examples to documentation |
#338 | Visually improve code generation logging |
#339 | Removed skipping of unreferenced UDT's, ENUM's and ARRAY's |
#342 | Improved generated referential code by using fetch() and fetchOne() API |
#356 | Let UpdatableRecord.store() and delete() return an int to indicate whether the record was actually modified |
API changes
#233 | Allow for joining TableLike instead of Table |
#337 | Added generic type <R extends TableRecord<R>> to InsertSelectQuery |
#341 | Fixed API flaw where SelectOnConditionStep.and() methods and similar ones returned SelectConditionStep, instead of SelectOnConditionStep |
Bugfixes
#69 | Corrected referential code generation for foreign keys that reference non-primary unique keys |
#85 | Corrected referential code generation for multi-field foreign keys |
#121 | Covered more Factory.executeXXX() methods with integration tests |
#318 | Fixed NullPointerException when executing SELECT * from aliased tables |
#321 | BetweenCondition does not bind left hand side Field correctly |
#322 | InCondition does not bind left hand side Field correctly |
#326 | Avoid method overloading where binding <T> to Object may lead to compile-time ambiguities (with javac) |
#343 | Add more foreign key navigation method integration tests |
#347 | Add explicit integration tests for schema artefacts excluded from code generation |
#350 | Disambiguate navigation methods if several foreign keys reference the same entity |
#352 | Disambiguate navigation methods if a table ending on S references itself |
#353 | Added integration test for compilation of generated artefacts with javac (as opposed to the Eclipse compiler) |
#355 | Error when storing an UpdatableRecord that has no changed values |
Version 1.5.5.2 - March 15, 2011
A critical bug was reported from the 1.5 release stream where stored functions did not render their parameters in correct order
Features
#302 | Map Oracle's NUMBER data type to java.lang.Number in stored procedures, stored functions |
Bugfixes
#317 | StoredFunctionImpl.asField() renders parameters in wrong order |
Version 1.5.5.1 - March 13, 2011
In version 1.5.5, there was a fatal bug breaking Derby source code generation. Only the Derby dialect is affected. Please update immediately, if you are using jOOQ's Derby integration
Bugfixes
#315 | Generated master data records are not sorted by PK |
#316 | Derby code generation fatally broken |
Version 1.5.5 - March 12, 2011
This version is released early as there are some important bugfixes. Additional improvements include:
- Improved DSL related to conditions in HAVING and JOIN clauses
- Support for Oracle-style functions, such as NVL, NVL2, COALESCE DECODE, etc
Features
#304 | Add support for Oracle NVL function |
#305 | Add support for COALESCE function |
#308 | Add support for Oracle NVL2 function |
#311 | Add support for Oracle DECODE function |
API changes
#223 | Enhance DSL to accept and(), or() and similar methods in JOIN steps |
#224 | Enhance DSL to accept and(), or() and similar methods in HAVING steps |
Bugfixes
#297 | Fixed Factory.concatenate() function |
#298 | Added integration tests for nested selects in HAVING clause |
#300 | Added integration tests for nested selects in JOIN clause |
#303 | Javadoc correction |
#307 | Accelerated integration tests |
#309 | Fixed JDBC variable binding issue related to Conditions where the lhs is a function (e.g. stored function) and the rhs is a constant |
#310 | Fixed issue where fetchOne() methods throw NullPointerException if no result record is available |
#312 | Fixed issue where Field.equal(...) methods rendered unexpected SQL when rhs null is cast to a type |
#313 | Fixed Derby cast type for VARCHAR |
#304 | Let the DerbyDataType default for java.lang.String be VARCHAR, not LONG VARCHAR |
Version 1.5.4 - March 04, 2011
Feature #243 required a minor API change in the base classes of generated source code. This means you have to re-generate all your jOOQ artifacts in order to migrate to 1.5.4. The artifacts themselves should be regenerated in a compatible way, such that your client code should not be affected. If this is not the case, please report a ticket here:
https://sourceforge.net/apps/trac/jooq/newticket
Apart from the Derby RDMBS and some new data type support, there have been many new convenience methods added all over the API. For instance, if type-safety is not really a requirement, there are lots of possibilities to use plain SQL directly in the DSL. In that case, data can be accessed from Record, Results, not only through Field<?>, but also through field names or indexes.
Check out the updated documentation (soon) here:
https://sourceforge.net/apps/trac/jooq/wiki/Examples
- Support for the Derby RDBMS
- Support for casting. This allows for even greater flexibility in cases where jOOQ cannot 100% ensure type-safety
- Support for ARRAY types. Oracle, Postgres, HSQLDB and H2 ARRAY types are now supported natively as regular <T> bindings in jOOQ's Field<T>
- Support for dialect-specific data types. CHAR, VARCHAR, CLOB are no longer treated equally as java.lang.String. Their type heritage is also generated
- More sequence support
- Lots and lots of bug fixes
Features
#95 | Support for the Derby RDMBS |
#163 | Add support for JDBC type ARRAY (with Postgres) |
#209 | Add support for DB2 sequences |
#210 | Add support for H2 sequences |
#211 | Add support for HSQLDB sequences |
#215 | Support for SQL casting using <T> as cast type |
#246 | Support for SQL casting using dialect-specific data types |
#254 | Add HSQLDB support for ARRAY types |
#256 | Add Oracle support for VARRAY types |
#257 | Integrate ARRAY types with stored procedures |
#261 | Add a global type mapping to the generated Schema object |
#267 | Add DataTypeDefinition for further abstraction of data types in code generation |
#269 | Add H2 support for ARRAY types |
#290 | If log4j is not on the classpath, use java.util.logging instead, as fallback |
API Changes
#156 | Allow for results to be accessed by index, not by field |
#218 | Corrected bad method signature: Record.getValueAsLong(Field<?>, Integer) |
#219 | Extended Result and Select API's to be more similar to that of Record |
#232 | Add more convenience plain SQL support to the API |
#235 | Add convenience methods to Record, Result and Select for access of data via field name |
#243 | Refactor DataType implementations in order to allow for the use of generics |
#259 | Add field type to database meta data (ColumnDefinition) |
#260 | Add field type to database meta data (Field<?>) |
#262 | Add default behaviour for Record.getValue(Field<?>) |
#276 | Add Javadoc as a ZIP file to the jOOQ distribution |
Bugfixes
#125 | Add more plain SQL integration tests |
#191 | Add more integration tests for nested unions |
#205 | Implemented workaround for handling Postgres stored functions with UDT OUT parameters |
#214 | Fixed NPE when generating a stored function with an unknown parameter type |
#216 | Fixed some cases where binding of BigInteger is not done correctly |
#220 | Syntax error when using select statement in a CASE clause |
#221 | Corrected integration tests for combined update and select statements |
#222 | Added integration test for INSERT statements having nested SELECT statements for their fields |
#225 | Correctly cast array types in Postgres |
#230 | Potential misuse of Blob and Clob in H2's JDBC types |
#239 | Factory.fetchAny() is not implemented for SQLite |
#244 | Fixed peculiar MySQL casting support where cast types do not match any data types |
#245 | Fixed NPE when reading null dates in SQLite |
#249 | Added ARRAY type integration tests |
#255 | Stored procedure bind variables get mixed up when any argument is null |
#263 | Correctly handle Postgres function overloading |
#264 | Ambiguous funciton calls when calling overloaded functions with null parameter |
#281 | Handle compilation errors when generating stored procedures with > 254 parameters |
#283 | Fixed compilation errors in generated source code for Oracle's UDT table type |
#284 | Fixed compilation errors in generated source code for Oracle procedures in packages, when they have no parameters |
#285 | Fixed compilation errors in generated source code for Oracle tables with the same name in different schemata |
#286 | Fixed name collisions in generated objects with the java.lang.* package |
#288 | Prevent the creation of UNION queries with bad syntax in MySQL |
#289 | Correctly alias fields within UNION queries for some dialects, which then only require the "AS" keyword |
#291 | Cannot create an aliased field called "year" in Postgres |
Version 1.5.3 - January 13, 2011
- Lots of stored procedure support was implemented
- Support for sequences was added
- The final decision to postpone support for DB2 UDT's was made
- Some code generation bugfixes
Features
#36 | Added stored procedure / stored function support for HSQLDB |
#140 | Added support for Oracle sequences |
#147 | Added support for H2 stored functions |
#162 | Correctly integrate UDTs with stored procedures |
#170 | Added support for Postgres stored functions |
#186 | Added support for more Oracle PL/SQL simple data types |
#193 | Simulate support for H2 "stored procedures" |
#195 | Simulate support for Postgres "stored procedures" |
#206 | Added support for Postgres sequences |
API changes
#180 | Improved DSL for constant values |
#181 | Allow for referencing Field<?> in function argument list |
#189 | Renamed convenience methods in org.jooq.Record |
#207 | Add fetchOne(Field) method to org.jooq.Select API |
Bugfixes
#182 | Protected generated Record classes against clashes with inherited methods |
#183 | Fixed NullPointerException, when generating master data tables with NULL fields |
#184 | Fixed IllegalArgumentException, when a data type is present in the schema, but unavailable in code generation logic |
#185 | Code generation should not fail when single elements cannot be generated |
#188 | Improved integration tests for stored procedures / functions / packages |
#196 | Increase RDMBS version compatibility by avoiding "SELECT *" in code generation logic |
#199 | Added integration tests for stored procedures in RDBMS that do not support OUT parameters |
#201 | Fixed issue in DB2 where stored procedures without parameters were not generated. |
#202 | Added integration tests for stored procedures / functions without parameters |
Version 1.5.2 - December 27, 2010
- Improved support for stored procedures, also in packages
- A minor API change was inevitable to implement #173. The API change only concerns the INTERNAL API. Deprecation marks are added and deprecated items will be removed in 1.6.0
- Experimental SQLite database support
- Some important bug fixes
Features
#25 | Added support for Oracle packages |
#114 | Added support for Oracle UDTs |
#145 | Added support for the SQLite database |
#150 | Generate static convenience methods for stored procedures / functions |
#151 | Generate static convenience methods for stored function fields |
#152 | Generate meaningful serialVersionUID in generated classes |
#173 | Added support for EQUIVALENT schemata |
API changes
#159 | Added convenience method List<T> getValues(Field) to Result |
#165 | Added convenience methods for creating EXISTS clauses |
#169 | Improved DSL for WHERE clauses |
Bugfixes
#68 | Prevent issues originating from overloaded stored procedure names, generating identical Java class names |
#153 | Fixed issue with generated code for DB2 stored functions |
#154 | Fixed issue with generated code for DB2 stored functions |
#155 | Fixed issues with database NULL not being mapped correctly to Java NULL when selecting values that have a primitive type (int, long, etc) |
#158 | Potential ClassCastException when using Field<BigInteger> |
#171 | Corrected issue related to selection of default schema in DB2 |
#177 | Fixed issue related to generated code for tables or UDTs without columns |
Version 1.5.1 - December 13, 2010
- H2 database support thanks to Espen Stromsnes
- Improved stored procedure support
Features
#96 | Added H2 database support |
#101 | Added stored procedure / stored function support for Oracle |
#138 | Added stored procedure support for DB2 |
#146 | Added support for DB2 functions |
API changes
#143 | Added convenience methods to Record |
Bugfixes
#84 | Implemented referential code generation for foreign keys that do not match their primary keys' types |
#141 | Encoding problem in generated master data classes |
Version 1.5.0 - November 22, 2010
- A big one. Major API changes / improvements
- Added lots of convenience methods
- UDT support
- Enum support
- DB2 support thanks to Espen Stromsnes
- "Light" dependency to log4j added. jOOQ will still run without it
Features
#1 | Create support for UDTs (so far only for PostgreSQL) |
#15 | Added DB2 support |
#60 | Added support for nested selects in INSERT and UPDATE statements |
#83 | Added log4j logging to code generation and runtime |
#87 | Add support for arithmetic expressions |
#105 | Added support for ENUM data types, where applicable (MySQL and PostgreSQL so far) |
#110 | Added execute and fetch convenience methods |
#111 | Added missing "select distinct" support |
#122 | Annotate generated classes with javax.annotation.Generated |
#123 | Generate user enum fields from data values (master data) |
#124 | Added PlainSQLTable |
#127 | Added not() operator to Condition |
#135 | Added convenience methods andNot() and orNot() in Condition |
API changes
#89 | Removed support for DataSource. jOOQ is not a transaction manager |
#92 | Added SortField type to be used for sorting |
#99 | Provide better access to functions (No more FunctionFactory) |
#116 | Merge Manager functionality into Factory |
#118 | Improve API of org.jooq.Field |
#119 | Improve subquery condition API |
#132 | Reduced much of the select query API |
#134 | Better separation of SelectQuery and SimpleSelectQuery |
Bugfixes
#109 | Error when executing select * if generated schema does not match actual schema |
#115 | Fix various "null" pseudo field issues |
#126 | Error when selecting a single field from a union nested select |
#129 | Fixed performance issue in Oracle code generation for very large databases |
Version 1.4.4 - November 22, 2010
Unreleased version, fixes included in 1.5.0
Bugfixes
#133 | JoinCondition does not take comparison operator |
Version 1.4.3 - October 25, 2010
Some more bugfixes
Bugfixes
#71 | Generated code does not compile, when foreign key and primary key have a data type mismatch |
#73 | In Oracle generated code, multi-field foreign keys may generated bad relations code |
#82 | Conversion of literals to camelcase fails if numbers are involved |
Version 1.4.2 - October 22, 2010
Various bugfixes and minor improvements
Features
#66 | Add support for CASE or DECODE expression |
API changes
#77 | Functions should not extend FieldImpl, but a new AbstractField |
#78 | QueryPart pollutes declared method space of its implementations. Hide it by indirection |
Bugfixes
#64 | Code generation fails when foreign key references a unique key that is not the primary key. Code generation for these cases is omitted |
#67 | When loading properties files, a leading / seems to be mandatory. This is preventing users from correctly setting up jOOQ the first time |
#70 | Add support for Oracle datatype TIMESTAMP(6) |
#72 | Name clashes in generated Tables |
#75 | Constant does not bind its values. |
#76 | Constant should not render strings all the time |
#79 | Constants are not properly escaped |
#80 | Position function does not bind any variables |
#81 | Add cast function to Constants in HSQL |
Version 1.4.1 - October 18, 2010
Oracle patch release
Features
#63 | Generate referential functionality for Oracle |
Version 1.4.0 - October 17, 2010
Support for PostGreSQL was added. Added lots of OR-mapping functionality. There is a general API change due to various new features.
Features
#14 | Add PostGreSQL support |
#40 | Resolve foreign keys. Allow for navigation between objects. |
#42 | Add PlainSQLField |
#45 | Add "dirty" flag to Record's values. This allows for updating only relevant data. |
#47 | Complete implementation for UPDATE, INSERT, DELETE statements. Added some missing functionality. |
#48 | Add more support for Date, Time, Timestamp fields. |
#51 | Add a org.jooq.impl.Manager class that provides common utility methods for CRUD operations |
API changes
#10 | Add second generic type <R extends Record>. This is a prerequisite for many OR-mapping features |
#18 | Use org.jooq.Record in InsertQuery and UpdateQuery |
#46 | Create UpdatableRecords as a prerequisite for JPA and true OR-mapping. These records support store() and delete() methods |
#52 | Add default constructor in generated Records. |
#53 | Add refresh functionality to UpdatableRecords. See also #46 |
#54 | Add a state to the factory class |
#56 | Reduce API, remove unnecessary Condition subinterfaces |
#57 | Reduce API, remove unnecessary QueryPart interfaces |
Bugfixes
#49 | NullPointerException when generating relations on schema subset |
#58 | Count function renders bad SQL in various dialects |
#59 | Exception when selecting unaliased functions in queries |
Version 1.3.0 - August 24, 2010
Support for HSQLDB was added. There is a major API change due to #44.
Features
#29 | Generate primary keys and foreign keys in Oracle code generation |
#34 | Add support for HSQLDB |
#39 | Generate primary keys and foreign keys in HSQLDB code generation |
#41 | Add documentation to QueryFactory and Functions |
API changes
#23 | Add support for more advanced joins |
#32 | Merge SelectQuery and ResultProviderQuery interfaces |
#44 | Let Query methods return "this" |
Bugfixes
#35 | Add unit tests for HSQLDB support |
#37 | Syntax error in combined select queries! The usage of combined queries in MySQL may still be a bit awkward. Keep an eye out for further fixes |
#43 | Join with aliased tables doesn't work |
Version 1.2.0 - August 21, 2010
The added Oracle support is now unit tested and more stable. The Oracle NUMBER data type is mapped more precisely to Java types.
Features
#12 | Model primary keys and foreign keys in generated code |
#22 | Improve mapping of Oracle NUMBER data type |
#26 | Add Plain SQL QueryParts |
#27 | Add support for HAVING clause |
Bugfixes
#24 | Add Unit tests for oracle database (and fixed bugs) |
#31 | Pull up addOrderBy() methods from SelectQuery to ResultProviderQuery |
Version 1.1.0 - August 17, 2010
The main new feature is the Oracle support. Wait for Version 1.1.1 for that support to be stabilised, as there are no Oracle unit tests running against an Oracle database yet.
Features
#2 | Add support for inner / nested selects |
#3 | Add more function support |
#4 | Implement filtering functionality for code generation |
#6 | Add Oracle Support |
#9 | Create true POJO's (implementing org.jooq.Record) with getters and setters |
#17 | Make org.jooq.impl.Parameter independent of Field |
Bugfixes
#11 | Code generation does not remove files |
Version 1.0.1 - August 14, 2010
Features
#5 | Prevent code regeneration, if no changes were made |
#7 | Implement ant task for code generation |