Skip to content
This repository was archived by the owner on Jun 11, 2023. It is now read-only.

Upgrade to querydsl 5.0.0 & hibernate 6.1.7-final #9

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
0.0.9-SNAPSHOT:
- updated to spring-boot 3.1 and hibernate 6.2
- generation of full-parametric SQL queries (previous version generated mixed parametric / static queries, which required messing with Hibernate internals and moreover could lead to SQL injections)
- updated postgresql testcontainer to version 15
116 changes: 107 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,24 @@

<groupId>com.github.alexliesenfeld</groupId>
<artifactId>querydsl-jpa-postgres-json</artifactId>
<version>0.0.7-SNAPSHOT</version>
<version>0.0.9-SNAPSHOT</version>

<name>${project.groupId}:${project.artifactId}</name>
<description>Querydsl extension for using PostgreSQL JSON types with JPA</description>
<url>https://github.com/alexliesenfeld/querydsl-jpa-postgres-json</url>

<properties>
<java.version>1.8</java.version>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<querydsl.version>4.2.1</querydsl.version>
<hibernate.version>5.2.10.Final</hibernate.version>
<lombok.version>1.18.8</lombok.version>
<jackson.version>2.10.0</jackson.version>
<querydsl.version>5.0.0</querydsl.version>
<!-- spring boot 3.1.2 versions -->
<hibernate.version>6.2.6.Final</hibernate.version>
<lombok.version>1.18.28</lombok.version>
<jackson.version>2.15.2</jackson.version>
<hypersistence.version>3.5.1</hypersistence.version>
<spring-boot.version>3.1.2</spring-boot.version>
</properties>

<dependencies>
Expand All @@ -34,14 +37,19 @@
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
<classifier>jakarta</classifier>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.hypersistence</groupId>
<artifactId>hypersistence-utils-hibernate-60</artifactId>
<version>${hypersistence.version}</version>
</dependency>

<dependency>
Expand All @@ -51,11 +59,64 @@
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${spring-boot.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>${spring-boot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<version>1.17.3</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.3.8</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<classifier>jakarta</classifier>
<scope>test</scope>
</dependency>
<!-- Query dsl -->
</dependencies>



<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
Expand All @@ -67,7 +128,7 @@

<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<version>3.1.1</version>
<executions>
<execution>
<id>default-deploy</id>
Expand Down Expand Up @@ -130,6 +191,43 @@
</execution>
</executions>
</plugin>

<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<id>generate-test-entities</id>
<phase>generate-test-sources</phase>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-test-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.hibernate.orm.tooling</groupId>
<artifactId>hibernate-enhance-maven-plugin</artifactId>
<version>${hibernate.version}</version>
<executions>
<execution>
<id>enhance</id>
<goals>
<goal>enhance</goal>
</goals>
<configuration>
<enableLazyInitialization>true</enableLazyInitialization>
<enableDirtyTracking>true</enableDirtyTracking>
<enableAssociationManagement>true</enableAssociationManagement>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Preconditions;
import com.querydsl.core.types.Path;
import com.querydsl.core.types.PathMetadata;
import com.querydsl.core.types.PathMetadataFactory;
import com.querydsl.core.types.Visitor;
import com.querydsl.core.types.dsl.*;
import lombok.Getter;
import org.hibernate.AssertionFailure;
import org.hibernate.annotations.Type;

import java.lang.reflect.AnnotatedElement;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import lombok.Getter;
import org.hibernate.annotations.Type;

/**
* @author <a href=http://github.com/wenerme>wener</a>
Expand Down Expand Up @@ -50,7 +49,7 @@ public static boolean isJsonb(Path<?> path) {
}
Type type = path.getAnnotatedElement().getAnnotation(Type.class);
if (type != null) {
return type.type().contains("jsonb");
return type.value().getName().contains("JsonBinaryType");
}
return false;
}
Expand Down Expand Up @@ -82,9 +81,8 @@ public AnnotatedElement getAnnotatedElement() {
return parent.getAnnotatedElement();
}

@Nullable
@Override
public <R, C> R accept(Visitor<R, C> v, @Nullable C context) {
public <R, C> R accept(Visitor<R, C> v, C context) {
// NOTE HQL does not support nested functions, so hql_json_path(hql_json_path(?,?),?) will fail
throw new AssertionError("This should not happen");
}
Expand Down Expand Up @@ -247,6 +245,7 @@ private String toJsonString(Object value){
}
}
protected void checkJsonb() {
Preconditions.checkArgument(isJsonb(), "This function required jsonb type");
if(!isJsonb())
throw new AssertionFailure("This function required jsonb type");
}
}
Original file line number Diff line number Diff line change
@@ -1,86 +1,58 @@
package com.github.alexliesenfeld.querydsl.jpa.hibernate;

import java.sql.Types;
import java.util.function.BiConsumer;

import com.github.alexliesenfeld.querydsl.jpa.hibernate.functions.types.*;
import io.hypersistence.utils.hibernate.type.json.internal.JsonBinaryJdbcTypeDescriptor;

import com.github.alexliesenfeld.querydsl.jpa.hibernate.functions.JsonFunction;
import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.dialect.PostgresPlusDialect;
import org.hibernate.service.ServiceRegistry;

import com.github.alexliesenfeld.querydsl.jpa.hibernate.functions.types.*;
import org.hibernate.dialect.PostgreSQL95Dialect;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.type.IntegerType;
import org.hibernate.type.StringType;
import org.hibernate.type.Type;
import java.sql.Types;

/**
* @author <a href=http://github.com/wenerme>wener</a>
* @author <a href=http://github.com/alexliesenfeld>Alexander Liesenfeld</a>
* @see <a href=https://www.postgresql.org/docs/current/static/functions-json.html>functions-json</a>
*/
public class PostgreSQLJsonDialect extends PostgreSQL95Dialect {
private final BiConsumer<Integer, String> registerColumnTypeConsumer;
private final BiConsumer<String, SQLFunction> registerFunctionConsumer;
public class PostgreSQLJsonDialect extends PostgresPlusDialect {

/**
* You can either directly use it or derive your custom dialect by using this constructor.
*/
public PostgreSQLJsonDialect() {
super();

this.registerColumnTypeConsumer = this::registerColumnType;
this.registerFunctionConsumer = this::registerFunction;

register();
}

/**
* Use this constructor if you cannot use or derive from this dialect class. You can create a new instance by
* using this constructor and register the provided functionality by calling the
* {@link PostgreSQLJsonDialect#register()} function. This will still allow you to use the functionality provided
* by this dialect but you do not need to use or derive from this dialect class.
*
* @param registerColumnTypeConsumer A reference to the {@link PostgreSQL95Dialect#registerColumnType(int, String)}
* function this class should be using. If you do not have any custom functions
* for this, just pass <code>this::registerColumnType</code>, where
* <code>this</code> refers to your dialect class calling this constructor.
*
* @param registerFunctionConsumer A reference to the
* {@link PostgreSQL95Dialect#registerFunction(String, SQLFunction)} (int, String)}
* function this class should be using. If you do not have any custom functions for
* this, just pass <code>this::registerFunction</code>, where <code>this</code>
* refers to your dialect class calling this constructor.
*/
public PostgreSQLJsonDialect(BiConsumer<Integer, String> registerColumnTypeConsumer, BiConsumer<String, SQLFunction> registerFunctionConsumer) {
super();

this.registerColumnTypeConsumer = registerColumnTypeConsumer;
this.registerFunctionConsumer = registerFunctionConsumer;
@Override
public void initializeFunctionRegistry(FunctionContributions functionContributions) {
super.initializeFunctionRegistry(functionContributions);

register();
}
functionContributions.getFunctionRegistry().register("hql_json_text", new TextJsonSQLFunction());
functionContributions.getFunctionRegistry().register("hql_json_int", new IntJsonSQLFunction());
functionContributions.getFunctionRegistry().register("hql_json_float", new FloatJsonSQLFunction());
functionContributions.getFunctionRegistry().register("hql_json_double", new DoubleJsonSQLFunction());
functionContributions.getFunctionRegistry().register("hql_json_long", new LongJsonSQLFunction());
functionContributions.getFunctionRegistry().register("hql_json_short", new ShortJsonSQLFunction());
functionContributions.getFunctionRegistry().register("hql_json_bool", new BoolJsonSQLFunction());

public void register() {
this.registerColumnTypeConsumer.accept(Types.JAVA_OBJECT, "jsonb");
this.registerColumnTypeConsumer.accept(Types.JAVA_OBJECT, "json");
functionContributions.getFunctionRegistry().register("hql_json_" + "array_length", new LongJsonSQLFunction());
functionContributions.getFunctionRegistry().register("hql_jsonb_" + "array_length", new LongJsonSQLFunction().setJsonb(true));

this.registerFunctionConsumer.accept("hql_json_text", new TextJsonSQLFunction());
this.registerFunctionConsumer.accept("hql_json_int", new IntJsonSQLFunction());
this.registerFunctionConsumer.accept("hql_json_float", new FloatJsonSQLFunction());
this.registerFunctionConsumer.accept("hql_json_double", new DoubleJsonSQLFunction());
this.registerFunctionConsumer.accept("hql_json_long", new LongJsonSQLFunction());
this.registerFunctionConsumer.accept("hql_json_short", new ShortJsonSQLFunction());
this.registerFunctionConsumer.accept("hql_json_bool", new BoolJsonSQLFunction());
functionContributions.getFunctionRegistry().register("hql_json_" + "typeof", new LongJsonSQLFunction());
functionContributions.getFunctionRegistry().register("hql_jsonb_" + "typeof", new LongJsonSQLFunction().setJsonb(true));

this.registerJsonFunction("array_length", IntegerType.INSTANCE);
this.registerJsonFunction("typeof", StringType.INSTANCE);

this.registerFunctionConsumer.accept("hql_jsonb_contains", new JsonContainsSQLFunction().setJsonb(true));
}
functionContributions.getFunctionRegistry().register("hql_json_contains", new JsonContainsSQLFunction());
functionContributions.getFunctionRegistry().register("hql_jsonb_contains", new JsonContainsSQLFunction().setJsonb(true));

private void registerJsonFunction(String name, Type type) {
this.registerFunctionConsumer.accept("hql_json_" + name, new JsonFunction(type, name));
this.registerFunctionConsumer.accept("hql_jsonb_" + name, new JsonFunction(type, name).setJsonb(true));
}

@Override
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
super.contributeTypes(typeContributions, serviceRegistry);
typeContributions.getTypeConfiguration().getJdbcTypeRegistry().addDescriptor(Types.JAVA_OBJECT, new JsonBinaryJdbcTypeDescriptor());
typeContributions.getTypeConfiguration().getJdbcTypeRegistry().addDescriptor(Types.JAVA_OBJECT, new JsonBinaryJdbcTypeDescriptor());
}
}
Loading