Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 2 additions & 32 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,50 +19,20 @@ jobs:
if: ${{ !contains(github.event.head_commit.message, '[skip tests]') }}
name: "Test"
runs-on: ubuntu-24.04
container: ubuntu
services:
postgres:
image: postgres
env:
POSTGRES_DB: pg_extensions_test
POSTGRES_USER: postgres_extensions
POSTGRES_PASSWORD: postgres_extensions
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres_extensions -d pg_extensions_test"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Install psql client
env:
DEBIAN_FRONTEND: noninteractive
run: |
apt-get update
apt-get install -y --no-install-recommends postgresql-client
- name: Create extensions
env:
PGPASSWORD: postgres_extensions
run: |
until pg_isready -h postgres -p 5432 -U postgres_extensions -d pg_extensions_test; do sleep 1; done
psql -h postgres -U postgres_extensions -d pg_extensions_test -c "CREATE EXTENSION IF NOT EXISTS hstore;"
- name: "📥 Checkout repository"
uses: actions/checkout@v5
- name: "☕️ Setup JDK"
uses: actions/setup-java@v5
with:
java-version: 17
java-version: 21
distribution: liberica
- name: "🐘 Setup Gradle"
uses: gradle/actions/setup-gradle@v4
with:
develocity-access-key: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
- name: "🏃‍♂️ Run Checks"
id: build
env:
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
run: ./gradlew check --continue
publish_snapshot:
needs: tests
Expand All @@ -76,7 +46,7 @@ jobs:
- name: "☕️ Setup JDK"
uses: actions/setup-java@v4
with:
java-version: 17
java-version: 21
distribution: liberica
- name: "🐘 Setup Gradle"
uses: gradle/actions/setup-gradle@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
types: [ published ]
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
JAVA_VERSION: '17.0.15' # this must be a specific version for reproducible builds
JAVA_VERSION: '21.0.12' # this must be a specific version for reproducible builds
RELEASE_TAG_PREFIX: 'v'
jobs:
publish:
Expand Down
2 changes: 1 addition & 1 deletion .sdkmanrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Enable auto-env through the sdkman_auto_env config - https://sdkman.io/usage#env
java=17.0.15-librca
java=21.0.12-librca
7 changes: 0 additions & 7 deletions Dockerfile

This file was deleted.

53 changes: 51 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ More native types and query methods will be added in the future.

## Installation

The Grails 7 version of this plugin supports Hibernate 5.
In `build.gradle` add the following dependencies to install the plugin:
The Grails 8 version of this plugin supports both Hibernate 5 and Hibernate 7, with a plugin for each.
In `build.gradle` add the dependencies for the Hibernate version of your application.

Hibernate 5:

```groovy
dependencies {
Expand All @@ -59,6 +61,51 @@ dependencies {
}
```

Hibernate 7:

```groovy
dependencies {
//...
implementation 'io.github.gpc:grails-postgresql-extensions-hibernate7:<version>'
implementation 'org.apache.grails:grails-data-hibernate7'
//...
}
```

Both plugins provide the same user types, dialect, criteria and orders, in the same packages, so the domain classes
and queries of an application do not change when it moves from Hibernate 5 to Hibernate 7.

> [!NOTE]
> With GORM 8.0.0 for Hibernate 7, the default `native` id generator does not create its sequences on PostgreSQL
> ([apache/grails-core#16561](https://github.com/apache/grails-core/issues/16561)).
> Until this is fixed in GORM, use the `sequence` generator in `grails-app/conf/application.groovy`:
>
> ```groovy
> grails.gorm.default.mapping = {
> id generator: 'sequence'
> }
> ```

### Upgrading to 9.0.0

- The Hibernate independent classes, like `HstoreHelper` and `PgArrayUtils`, moved to the
`grails-postgresql-extensions-core` module, which both plugins depend on. Their packages did not change.
- `PgArrayUtils.getValueAsArrayOfType` now throws an `IllegalArgumentException` instead of a `HibernateException` for
values of an unsupported type. The array criteria still throw a `HibernateException`.

### Hibernate 7 limitations

GORM 8.0.0 for Hibernate 7 has no API for custom criteria to use the joins of the query, or to order by an SQL formula
([apache/grails-core#16563](https://github.com/apache/grails-core/issues/16563)), so the plugin works around it:

- A criterion on an alias created with `createAlias` uses the same join as the GORM criteria on the alias, when the
alias uses an inner join. GORM 8.0.0 creates the join of an alias as an inner join even when `createAlias` asks for an
outer join ([apache/grails-core#16562](https://github.com/apache/grails-core/issues/16562)), so for an outer join alias the criteria of the plugin use an
outer join, but GORM criteria on the same alias do not.
- `order(sqlFormula(...))` and `order(byRandom())` are added to the orders when the query is created, in the position
they were called in. Calling them inside `or {}` or `not {}` does not change the result of the junction.
An `or {}` that only contains such an order is empty, which matches no rows.

## Configuration

After installing the plugin you have to use a new PostgreSQL Hibernate Dialect in your application. Add it to the
Expand Down Expand Up @@ -655,6 +702,8 @@ if not you'll get a sql error during runtime.

## Release Notes

From 8.0.0 and forward release notes can be found on [GitHub](https://github.com/gpc/grails-postgresql-extensions/releases)

Version | Date | Comments
------- | ------------| ---------
7.0.0 | 29/Jul/2019 | Grails 4 (Hibernate 5.4): Add support for Grails 4 and Hibernate 5.4. Thanks to [James Hardwick](https://github.com/jamesdh) and [Zhuravskiy Vitaliy](https://github.com/zhuravskiy).
Expand Down
39 changes: 38 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,43 @@
version = projectVersion
group = 'io.github.gpc'

def publishedProjects = [
'grails-postgresql-extensions-core',
'grails-postgresql-extensions',
'grails-postgresql-extensions-hibernate7',
]

ext.pgextDevelopers = [
ilopmar: 'Iván López',
alotor: 'Alonso Torres',
mattfeury: 'Matt Feury',
alvarosanchez: 'Alvaro Sanchez-Mariscal',
aeischeid: 'Aaron Eischeid',
mkobel: 'Moritz Kobel',
manuelvio: 'Manuel Unno Vio',
bameda: 'David Barragán Merino',
nobeans: 'Yasuharu Nakano',
burtbeckwith: 'Burt Beckwith',
timic: 'Timur Salyakhutdinov',
zlegein: 'Zach Legein',
tmarthal: 'Tom Marthaler',
pabloalba: 'Pablo Alba',
cornercase: 'Eamon Doyle',
poundex: 'Adam Pounder',
gregopet: 'Gregor Petrin',
unknown: 'Tom Potts',
sabst: 'Sabst',
donbeave: 'Alexey Zhokov',
jglapa: 'Jakub Glapa',
jamesdh: 'James Hardwick',
butters16: 'John Keith',
erichelgeson: 'Eric Helgeson',
albertop19: 'albertop19',
gtors: 'Andrey T',
matrei: 'Mattias Reichel',
sbglasius: 'Søren Berg Glasius'
]

subprojects {

repositories {
Expand All @@ -17,7 +54,7 @@ subprojects {
}
}

if (name == 'grails-postgresql-extensions') {
if (name in publishedProjects) {
// This has to be applied here in the root project due to the nexus plugin requirements
apply plugin: 'org.apache.grails.gradle.grails-publish'
}
Expand Down
6 changes: 3 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
projectVersion=8.0.1-SNAPSHOT
projectVersion=9.0.0-SNAPSHOT

grailsVersion=7.0.0
javaVersion=17
grailsVersion=8.0.0
javaVersion=21

hibernate5Version=5.6.15.Final

Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
41 changes: 41 additions & 0 deletions plugin-core/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
plugins {
id 'groovy'
id 'java-library'
}

version = projectVersion
group = 'io.github.gpc'

grailsPublish {
artifactId = 'grails-postgresql-extensions-core'
githubSlug = 'gpc/grails-postgresql-extensions'
license.name = 'Apache-2.0'
title = 'Grails PostgreSQL Extensions Core'
desc = 'Hibernate-independent support code shared by the Grails PostgreSQL Extensions plugins.'
developers = rootProject.ext.pgextDevelopers
}

dependencies {

implementation platform("org.apache.grails:grails-bom:$grailsVersion")

compileOnly 'org.springframework:spring-core', { // Provided
// impl: Assert
}

implementation 'org.apache.groovy:groovy'
implementation 'org.slf4j:slf4j-api'
api 'org.postgresql:postgresql'

testImplementation 'org.spockframework:spock-core'

testRuntimeOnly 'org.springframework:spring-core', {
// Assert
}
}

compileJava.options.release = javaVersion.toInteger()

apply {
from rootProject.layout.projectDirectory.file('gradle/test-config.gradle')
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import java.lang.reflect.Array

import groovy.transform.CompileStatic

import org.hibernate.HibernateException

/**
* Utils for the different criteria queries.
*/
Expand Down Expand Up @@ -43,7 +41,7 @@ class PgArrayUtils {
if (mapFunction) {
return mapFunction.map(o)
}
throw new HibernateException("criteria doesn't support values of type: ${o?.class?.name}. Try: $expectedType or List<$expectedType> instead")
throw new IllegalArgumentException("criteria doesn't support values of type: ${o?.class?.name}. Try: $expectedType or List<$expectedType> instead")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the exception type for anyone calling PgArrayUtils directly (HibernateException -> IllegalArgumentException). Fine by me, but worth a line in the release notes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added an "Upgrading to 9.0.0" section to the README that mentions it (e095270), and I'll put it in the release notes when 9.0.0 is published.

}

converted.toArray((Object[]) Array.newInstance(expectedType, converted.size()))
Expand Down
36 changes: 36 additions & 0 deletions plugin-hibernate5/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
plugins {
id 'java-library'
id 'org.apache.grails.gradle.grails-plugin'
}

version = projectVersion
group = 'io.github.gpc'

grailsPublish {
artifactId = 'grails-postgresql-extensions'
githubSlug = 'gpc/grails-postgresql-extensions'
license.name = 'Apache-2.0'
title = 'Grails PostgreSQL Extensions Plugin'
desc = 'A Grails plugin that adds Hibernate UserTypes for PostgreSQL native types, ' +
'like Array, HStore, JSON, JSONB, ..., and GORM criteria extensions to query them.'
developers = rootProject.ext.pgextDevelopers
}

dependencies {

implementation platform("org.apache.grails:grails-bom:$grailsVersion")

api project(':grails-postgresql-extensions-core')

compileOnly 'org.apache.grails:grails-core', { // Provided
// impl: Plugin
}
compileOnly 'org.apache.grails:grails-data-hibernate5', {
// Must be provided by the Grails application
}

implementation 'com.google.code.gson:gson'
implementation "org.hibernate:hibernate-core-jakarta:$hibernate5Version"
}

compileJava.options.release = javaVersion.toInteger()
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class GrailsPostgresqlExtensionsGrailsPlugin extends Plugin {
[name: 'albertop19'],
[name: 'Andrey T'],
[name: 'Mattias Reichel'],
[name: 'Søren Berg Glasius'],
]
def issueManagement = [
system: 'GITHUB',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,10 @@ class PgArrayExpression implements Criterion {
private static final PgArrayUtils.MapFunction MAP_TO_ENUM = new PgArrayUtils.MapFunction() {
@Override
Object map(Object o) {
try {
if (o instanceof Enum) {
return ((Enum) o).ordinal()
} catch (ClassCastException e) {
throw new HibernateException("Unable to cast object $o to Enum", e)
}
throw new HibernateException("Unable to cast object $o to Enum")
}
}

Expand All @@ -50,9 +49,14 @@ class PgArrayExpression implements Criterion {
@Override
TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
def arrayType = checkAndGetArrayType(criteria, criteriaQuery, propertyName)
def arrValue = arrayType.typeClass.isEnum() ?
PgArrayUtils.getValueAsArrayOfType(value, Integer, MAP_TO_ENUM) :
PgArrayUtils.getValueAsArrayOfType(value, arrayType.typeClass)
Object[] arrValue
try {
arrValue = arrayType.typeClass.isEnum() ?
PgArrayUtils.getValueAsArrayOfType(value, Integer, MAP_TO_ENUM) :
PgArrayUtils.getValueAsArrayOfType(value, arrayType.typeClass)
} catch (IllegalArgumentException e) {
throw new HibernateException(e.message, e)
}
criteriaQuery.getTypedValue(criteria, propertyName, arrValue) as TypedValue[]
}

Expand Down
Loading
Loading