Hypersistence Utils

repository·master·Indexed 25 days ago

https://github.com/vladmihalcea/hypersistence-utils

General-purpose utilities for Spring and Hibernate providing advanced mapping for complex types such as JSON, arrays, and PostgreSQL-specific types. It supports a wide range of Hibernate versions (5.0 through 7.4) and includes features like the @Tsid annotation for time-sorted identifiers, BaseJpaRepository for Spring Data JPA, and StatelessSessionUtil for synchronized Hibernate StatelessSessions.

Tokens
2K
Snippets
3
Records
16
Agent score
82%

What's inside Hypersistence Utils

  1. Migrate from Hibernate Types 2.x to Hypersistence Utils 3.x

    master

    To migrate from the older Hibernate Types (2.x) to Hypersistence Utils (3.x), follow these three steps:

    1. Update your Maven or Gradle dependencies to the new Hypersistence Utils artifacts.
    2. Rename all packages from com.vladmihalcea.hibernate to io.hypersistence.utils.hibernate.
    3. Rename all Spring-related packages from com.vladmihalcea.spring to io.hypersistence.utils.spring.
  2. Use HibernateRepository to deprecate JpaRepository methods

    master

    If you must use the default JpaRepository, you can extend HibernateRepository to deprecate methods that cause issues.

    To enable this, you must include the io.hypersistence.utils.spring.repository package in your @EnableJpaRepositories configuration:

    @Configuration
    @EnableJpaRepositories(
        value = {
            "io.hypersistence.utils.spring.repository",
            "your.repository.package",
            ...
        }
    )
    public class JpaConfiguration {
        ...
    }
  3. Use BaseJpaRepository in Spring Data JPA

    master

    The BaseJpaRepository is an alternative to the default Spring Data JpaRepository. It avoids problematic methods like findAll() (which can cause performance issues) and save() (which doesn't align with JPA semantics).

    To use it, configure your @EnableJpaRepositories to use BaseJpaRepositoryImpl as the repositoryBaseClass:

    @Configuration
    @EnableJpaRepositories(
        value = "your.repository.package",
        repositoryBaseClass = BaseJpaRepositoryImpl.class
    )
    public class JpaConfiguration {
        ...
    }
  4. Install Hypersistence Utils for Hibernate

    master

    Add the dependency corresponding to your specific Hibernate version. Note that some versions require commercial support.

    Hibernate VersionMaven Artifact IDRecommended Version
    7.4, 7.3hypersistence-utils-hibernate-733.15.4
    7.2, 7.1hypersistence-utils-hibernate-713.15.4
    7.0hypersistence-utils-hibernate-703.15.4 (Commercial)
    6.6, 6.5, 6.4, 6.3hypersistence-utils-hibernate-633.15.4
    6.2hypersistence-utils-hibernate-623.9.4 (Commercial)
    6.1, 6.0hypersistence-utils-hibernate-603.9.4 (Commercial)
    5.6, 5.5hypersistence-utils-hibernate-553.9.5 (Commercial)
    5.4, 5.3, 5.2hypersistence-utils-hibernate-523.7.6 (Commercial)
    5.1, 5.0hypersistence-utils-hibernate-53.7.0 (Commercial)
  5. Configure Optional Maven Dependencies

    master

    Hypersistence Utils requires you to explicitly declare several optional dependencies depending on the features you use. You must manage these versions yourself to ensure security and compatibility.

    JSON Support

    For Hibernate 7 and 6:

    <dependency>
        <groupId>com.fasterxml.jackson.module</groupId>
        <artifactId>jackson-module-jakarta-xmlbind-annotations</artifactId>
        <version>${jackson-module-jakarta-xmlbind-annotation}</version>
    </dependency>

    For Hibernate 5:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson-databind.version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.module</groupId>
        <artifactId>jackson-module-jaxb-annotations</artifactId>
        <version>${jackson-module-jaxb-annotation}</version>
    </dependency>

    Other Optional Dependencies

    • Guava (for Range mapping): com.google.guava:guava
    • Java Money (for MonetaryAmount mapping): org.javamoney:moneta (type pom)
    • PostgreSQL (for inet, hstore, array, interval): org.postgresql:postgresql
  6. Map JSON columns using JsonType

    master

    Hibernate 7 and 6

    Use the @Type annotation directly on the entity property. You can map to Map, List, POJO, String, or JsonNode.

    @Type(JsonType.class)
    private Map<String, String> properties = new HashMap<>();

    Hibernate 5

    Option 1: Provide the fully-qualified name in @Type:

    @Type(type = "io.hypersistence.utils.hibernate.type.json.JsonType")
    private Map<String, String> properties = new HashMap<>();

    Option 2: Define a @TypeDef in your package-info.java to use a shorthand name:

    @TypeDef(
        name = "json", typeClass = JsonType.class
    )
    package io.hypersistence.optimizer;
    
    import io.hypersistence.utils.hibernate.type.json.JsonType;
    import org.hibernate.annotations.TypeDef;

    Then use the shorthand in your entity:

    @Type(type = "json")
    private Map<String, String> properties = new HashMap<>();

    Best Practice

    When mapping JSON to a POJO, List<POJO>, or Map<String, POJO>, ensure the POJO overrides equals and hashCode based on its JSON content to prevent unnecessary Hibernate dirty checking updates.

  7. Configure a custom TSID Factory with @Tsid

    master

    The @Tsid annotation allows you to specify a custom class that provides a TSID.Factory. By default, the annotation uses FactorySupplier.class, which provides a factory configured with TSID.Factory.THREAD_LOCAL_RANDOM_FUNCTION.

    To use a custom factory, provide a class that implements Supplier<TSID.Factory> to the @Tsid annotation value.

  8. Obtain a Hibernate StatelessSession using StatelessSessionUtil.statelessSession()

    master

    Use StatelessSessionUtil.statelessSession(EntityManager entityManager) to retrieve a Hibernate StatelessSession that is correctly synchronized with the current Spring transaction.

    This utility ensures that the same StatelessSession is reused within the same transaction by binding it to the TransactionSynchronizationManager using a StatelessSessionUtil key. If a session is already bound to the current transaction, it returns the existing one; otherwise, it opens a new StatelessSession using the current connection and binds it.

  9. Use the @Tsid annotation for automatic TSID generation

    master

    The @Tsid annotation can be applied to entity identifiers or other fields to automatically assign a time-sorted TSID.

    • On identifier fields: Uses TsidGenerator to handle value generation.
    • On non-identifier fields: Uses TsidValueGenerator to handle value generation.

    Supported field types:

    • Long
    • String
    • TSID (from the io.hypersistence.tsid package)