Skip to content

Add Hibernate 7 module #185

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Jul 9, 2025
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
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
groups:
github-actions:
patterns:
- "*"
2 changes: 1 addition & 1 deletion .github/workflows/dep_build_v2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
strategy:
fail-fast: false
matrix:
java_version: ['11', '17']
java_version: ['17', '21']
env:
JAVA_OPTS: "-XX:+TieredCompilation -XX:TieredStopAtLevel=1"
steps:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ jobs:
strategy:
fail-fast: false
matrix:
# 20-Dec-2022, tatu: Build now requires JDK 11; won't yet work with JDK 17
java_version: [ '11']
# Hibernate 7 requires Java 17+
java_version: [ '17', '21' ]
env:
JAVA_OPTS: "-XX:+TieredCompilation -XX:TieredStopAtLevel=1"
steps:
Expand Down
62 changes: 48 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ and properties; especially lazy-loading aspects.

As of version 2.0 module is usable and used by non-trivial number of developers and projects.

Note: Hibernate 4.x and 5.x are supported (5.x starting with Jackson 2.6),
but they require different jar, and Maven artifact names (and jar names differ).
This document refers to "Hibernate 5" version, but changes with 4.x should require
little more than replacing "5" in names with "4".
Note: Hibernate 4.x, 5.x, 6.x and 7.x are supported (5.x starting with Jackson 2.6; 6.x with Jackson 2.15 and 7.x with Jackson 2.20) but they require different jars, and Maven artifact names (and jar names differ).

This document refers to "Hibernate 5" version, but changes with 4.x/6.x/7.x should require
little more than replacing "5" in names with "4", "6" or "7".

Hibernate 3.x was supported up to Jackson 2.12 but is no longer supported at and after 2.13

Jackson 2.13 adds Support for "Hibernate 5 Jakarta" variant (for Hibernate 5.5 and beyond);
see below for more information.

Jackson 2.15 adds Support for Hibernate 6.x;
see below for more information.
Jackson 2.15 adds Support for Hibernate 6.x; see below for more information.

Jackson 2.20 adds Support for Hibernate 7.x; see below for more information.

### JDK requirements

Expand All @@ -31,6 +32,10 @@ With Jackson 2.15, JDK 11 will be required to build: all modules run on
Java 8 except for Hibernate 6.x module which requires Java 11 like
Hibernate 6.x itself.

With Jackson 2.20, JDK 17 will be required to build: 4.x and 5.x modules run on
Java 8, 6.x on 11 and Hibernate 7.x module requires Java 17 like
Hibernate 7.x itself.

### Javax vs Jakarta

Due to changes related to
Expand All @@ -54,7 +59,7 @@ To use module on Maven-based projects, use following dependency
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate5</artifactId>
<version>2.14.2</version>
<version>2.19.1</version>
</dependency>
```

Expand All @@ -66,7 +71,7 @@ Note that you need to use "jackson-datatype-hibernate4" for Hibernate 4.x.
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate4</artifactId>
<version>2.14.2</version>
<version>2.19.1</version>
</dependency>
```

Expand All @@ -77,17 +82,28 @@ you will need the jakarta suffixed dependency for Hibernate 5.5:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate5-jakarta</artifactId>
<version>2.14.2</version>
<version>2.19.1</version>
</dependency>
```

you will need to use "jackson-datatype-hibernate6" for Hibernate 6.x (when v2.15.0 is released):
but you will need to use "jackson-datatype-hibernate6" for Hibernate 6.x:
(for which only "jakarta" version exists).

```xml
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate6</artifactId>
<version>2.15.0</version>
<version>2.19.1</version>
</dependency>
```

and finally, for Hibernate 7.x

```xml
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate7</artifactId>
<version>2.19.1</version>
</dependency>
```

Expand All @@ -99,12 +115,30 @@ Like all standard Jackson modules (libraries that implement Module interface), r
ObjectMapper mapper = new ObjectMapper();
// for Hibernate 4.x:
mapper.registerModule(new Hibernate4Module());
// OR newer style
ObjectMapper mapper = JsonMapper.builder()
.addModule(new Hibernate4Module()));
.build();

// or, for Hibernate 5.x
mapper.registerModule(new Hibernate5Module());
ObjectMapper mapper = JsonMapper.builder()
.addModule(new Hibernate5Module()));
.build();

// or, for Hibernate 5.5+ with Jakarta
mapper.registerModule(new Hibernate5JakartaModule());
ObjectMapper mapper = JsonMapper.builder()
.addModule(new Hibernate5JakartaModule()));
.build();

// or, for Hibernate 6.x
mapper.registerModule(new Hibernate6Module());
ObjectMapper mapper = JsonMapper.builder()
.addModule(new Hibernate6Module()));
.build();

// or, for Hibernate 7.x
ObjectMapper mapper = JsonMapper.builder()
.addModule(new Hibernate7Module()));
.build();
```

after which functionality is available for all normal Jackson operations.
Expand Down
109 changes: 109 additions & 0 deletions hibernate7/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- This module was also published with a richer model, Gradle metadata, -->
<!-- which should be used instead. Do not delete the following line which -->
<!-- is to indicate to Gradle or any Gradle module metadata file consumer -->
<!-- that they should prefer consuming it instead. -->
<!-- do_not_remove: published-with-gradle-metadata -->
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate-parent</artifactId>
<version>2.20.0-SNAPSHOT</version>
</parent>
<artifactId>jackson-datatype-hibernate7</artifactId>
<name>Jackson-datatype-hibernate7</name>
<packaging>bundle</packaging>
<description>Add-on module for Jackson (https://github.com/FasterXML/jackson) to support
Hibernate (https://hibernate.org/) version 7.x with Jakarta data types.
</description>
<url>https://github.com/FasterXML/jackson-datatype-hibernate</url>
<properties>
<!-- Generate PackageVersion.java into this directory. -->
<packageVersion.dir>com/fasterxml/jackson/datatype/hibernate7</packageVersion.dir>
<packageVersion.package>${project.groupId}.hibernate7</packageVersion.package>
<!-- Hibernate with Jakarta Persistence 3.0 -->
<hibernate.version>7.0.3.Final</hibernate.version>
<osgi.export>${project.groupId}.hibernate7</osgi.export>
</properties>

<dependencies>
<dependency>
<groupId>jakarta.transaction</groupId>
<artifactId>jakarta.transaction-api</artifactId>
<version>2.0.1</version>
</dependency>

<!-- what would be the best scope to use here? -->
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
<scope>provided</scope>
</dependency>

<!-- and for some contributed tests Mockito -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>3.0.1</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<!-- Inherited from oss-base. Generate PackageVersion.java.-->
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
</plugin>
<!-- 29-Apr-2025, tatu: SBOM generation [JSTEP-14] -->
<plugin>
<groupId>org.cyclonedx</groupId>
<artifactId>cyclonedx-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.moditect</groupId>
<artifactId>moditect-maven-plugin</artifactId>
<inherited>true</inherited>
<configuration>
<jvmVersion>11</jvmVersion>
</configuration>
</plugin>
<!-- 05-Jul-2020, tatu: Add generation of Gradle Module Metadata -->
<!-- 28-Feb-2025, jjohannes: Apply plugin last as it has to be the last of all 'package phase' plugins -->
<plugin>
<groupId>org.gradlex</groupId>
<artifactId>gradle-module-metadata-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package com.fasterxml.jackson.datatype.hibernate7;

import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import jakarta.persistence.Transient;

/**
* Simple {@link AnnotationIntrospector} that adds support for using
* {@link Transient} to denote ignorable fields (alongside with Jackson
* and/or JAXB annotations).
*/
public class Hibernate7AnnotationIntrospector extends AnnotationIntrospector
{
private static final long serialVersionUID = 1L;

/**
* Whether we should check for existence of @Transient or not.
* Default value is 'true'.
*/
protected boolean _cfgCheckTransient = true;

/*
/**********************************************************************
/* Construction, configuration
/**********************************************************************
*/

public Hibernate7AnnotationIntrospector() { }

/**
* Method to call to specify whether @Transient annotation is to be
* supported; if false, will be ignored, if true, will be used to
* detect "ignorable" properties.
*/
public Hibernate7AnnotationIntrospector setUseTransient(boolean state) {
_cfgCheckTransient = state;
return this;
}

/**
* @since 2.5
*/
public boolean doesUseTransient() {
return _cfgCheckTransient;
}

/*
/**********************************************************************
/* Standard method impl/overrides
/**********************************************************************
*/

@Override
public Version version() {
return PackageVersion.VERSION;
}

/*
/**********************************************************************
/* Annotation introspection methods
/**********************************************************************
*/

@Override
public boolean hasIgnoreMarker(AnnotatedMember m) {
return _cfgCheckTransient && m.hasAnnotation(Transient.class);
}

@Override
public Boolean isIgnorableType(AnnotatedClass ac)
{
/* 26-Dec-2015, tatu: To fix [datatype-hibernate#72], need to suppress handling
* of `FieldHandled`. Not sure if it works without test (alas, none provided),
* but will try our best -- problem is, if it'
*/
// 11-Feb-2016, tatu: As per [datatype-hibernate#86] must use indirection. Sigh.
Class<?> handlerClass = FieldHandlerChecker.instance.getHandlerClass();
if (handlerClass != null) {
if (handlerClass.isAssignableFrom(ac.getAnnotated())) {
return Boolean.TRUE;
}
}
return null;
}

/**
* Helper class used to encapsulate detection of <code>FieldHandler</code>; class
* that was part of Hibernate from 4.0 until 5.0, but removed from 5.1.
*/
final static class FieldHandlerChecker {
private final static String FIELD_HANDLER_INTERFACE = "org.hibernate.bytecode.internal.javassist.FieldHandler";

private final Class<?> _handlerClass;

public final static FieldHandlerChecker instance = new FieldHandlerChecker();

public FieldHandlerChecker() {
Class<?> cls = null;
try {
cls = Class.forName(FIELD_HANDLER_INTERFACE);
} catch (Throwable t) { }
_handlerClass = cls;
}

public Class<?> getHandlerClass() {
return _handlerClass;
}
}
}
Loading
Loading