Search
Calendar
July 2025
S M T W T F S
« Jun    
 12345
6789101112
13141516171819
20212223242526
2728293031  
Archives

Posts Tagged ‘Hibernate’

PostHeaderIcon JpaSystemException: A collection with cascade=”all-delete-orphan” was no longer referenced by the owning entity instance

Case:

Entity declaration:

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Foo> foos = Lists.newArrayList();

This block

            user.getFoos().clear();
// instantiate `foos`, eg: final List<Foo> foos = myService.createFoos(bla, bla);
            user.setFoos(foos);

generates this error:

org.springframework.orm.jpa.JpaSystemException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: com.github.lalou.jonathan.blabla.User.foos

 Fix:

Do not use setFoos() ; rather, after clearing, use addAll(). In other words, replace:

            user.getFoos().clear();
            user.setFoos(foos);

with

user.getFoos().clear(); user.getFoos().addAll(foos);

 

(copied to https://stackoverflow.com/questions/78858499/jpasystemexception-a-collection-with-cascade-all-delete-orphan-was-no-longer )

PostHeaderIcon [Spring I/O 2023] Do You Really Need Hibernate?

Simon Martinelli’s thought-provoking session at Spring I/O 2023 challenges the default adoption of Hibernate in Java applications. With decades of experience, Simon advocates for jOOQ as a performant, SQL-centric alternative for database-centric projects. Using a track-and-field event management system as a case study, he illustrates how jOOQ simplifies data access, avoids common ORM pitfalls, and complements Hibernate when needed. This presentation is a masterclass in rethinking persistence strategies for modern Java development.

Questioning the ORM Paradigm

Simon begins by questioning the reflexive use of Hibernate and JPA in Java projects. While powerful for complex domain models, ORMs introduce overhead—such as dirty checking or persistence by reachability—that may not suit all applications. For CRUD-heavy systems, like his 25-year-old event management application, a simpler approach is often sufficient. By focusing on database tables rather than object graphs, developers can streamline data operations, avoiding the complexity of managing entity state transitions.

jOOQ: A Database-First Approach

jOOQ’s database-first philosophy is central to Simon’s argument. By generating type-safe Java code from database schemas, jOOQ enables developers to write SQL-like queries using a fluent DSL. This approach, as Simon demonstrates, ensures compile-time safety and eliminates runtime errors from mismatched SQL strings. The tool supports a wide range of databases, including legacy systems with stored procedures, making it versatile for both modern and enterprise environments. Integration with Flyway and Testcontainers further simplifies schema migrations and code generation.

Efficient Data Retrieval with Nested Structures

A highlight of Simon’s talk is jOOQ’s ability to handle nested data structures efficiently. Using the event management system’s ranking list—a tree of competitions, categories, athletes, and results—he showcases jOOQ’s MULTISET feature. This leverages JSON functionality in modern databases to fetch hierarchical data in a single SQL statement, avoiding the redundancy of JPA’s join fetches. This capability is particularly valuable for REST APIs and reporting, where nested data is common, eliminating the need for DTO mapping.

Combining jOOQ and Hibernate for Flexibility

Rather than advocating for jOOQ as a complete replacement, Simon proposes a hybrid approach. jOOQ excels in querying, bulk operations, and legacy database integration, while Hibernate shines in entity state management and cascading operations. By combining both in a single application, developers can leverage their respective strengths. Simon warns against using JPA for raw SQL, as it lacks jOOQ’s type safety, reinforcing the value of choosing the right tool for each task.

Practical Insights and Tooling

Simon’s demo, backed by a GitHub repository, illustrates jOOQ’s integration with Maven, Testcontainers, and a new Testcontainers Flyway plugin. He highlights practical considerations, such as whether to version generated code and jOOQ’s licensing model for commercial databases. The talk also addresses limitations, like MULTISET’s incompatibility with MariaDB, offering candid advice for database selection. These insights ground the presentation in real-world applicability, making it accessible to developers of varying experience levels.

A Call to Rethink Persistence

Simon’s presentation is a compelling call to reassess persistence strategies. By showcasing jOOQ’s performance and flexibility, he encourages developers to align their tools with application needs. His track-and-field application, evolved over decades, serves as a testament to the enduring value of SQL-driven development. For Java developers seeking to optimize data access, this talk offers a clear, actionable path forward, blending modern tooling with pragmatic wisdom.

Hashtags: #SpringIO2023 #jOOQ #Hibernate #Java #SQL #Database #SimonMartinelli #Testcontainers #Flyway

PostHeaderIcon (long tweet) You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘type=InnoDB’ at line 1

Stacktrace

org.hibernate.tool.hbm2ddl.SchemaExport - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'type=InnoDB' at line 1

Quick fix

In JPA configuration, replace:
datasource.dialect = org.hibernate.dialect.MySQLInnoDBDialect
with:
datasource.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
Actually, Java driver for MySQL 5.5+ is not backward compatible with the SQL dialect MySQLInnoDBDialect.

PostHeaderIcon (quick tutorial) Migration from MySQL to HSQLDB

Case

I got the project described in MK Yong’s website. This projects is a sample code of JSF + Spring + Hibernate. The laying DB is a MySQL. For many reasons, I’d rather not to detail, I prefered to a HSQLDB instead of the MySQL.

(Notice: the zip you can download at MK Yong’s website contains many errors, not related to the persistance layer but to JSF itself.)

How to migrate any project from MySQL to HSQLDB?

Solution

You have to follow these steps:

Maven

In the pom.xml, replace:

<!-- MySQL database driver -->
        <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.9</version>
        </dependency>

with:

        <!-- driver for HSQLdb -->
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <version>2.2.8</version>
        </dependency>

By the way, you can add Jetty plugin to have shorter development cycles:

            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>maven-jetty-plugin</artifactId>
                <configuration>
                    <webApp>${basedir}/target/jsf.war</webApp>
                    <port>8088</port>
                </configuration>
            </plugin>

Persistence

Properties

Replace the content of db.properties file with:

jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://localhost:9001
jdbc.username=sa
jdbc.password=

Hibernate Mapping

In the *.hbm.xml files:

  • in the tag <class>, remove the attribute catalog="..."
  • replace the types with fully qualified object types, eg:
    • long with java.lang.Long,
    • string with java.lang.String,
    • timestamp with java.util.Date,
    • etc.

Hibernate Properties

For the property of key hibernate.dialect, replace the value: org.hibernate.dialect.MySQLDialectorg.hibernate.dialect.HSQLDialect with the value: org.hibernate.dialect.HSQLDialect.
To match my needs, I tuned Hibernate properties a bit more, but it may not be needed in all situations:

        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hbm2ddl.auto">create-drop</prop>
                <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
                <prop key="connection.pool_size">1</prop>
                <prop key="current_session_context_class">thread</prop>
                <prop key="cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
            </props>
        </property>

Run

Run the HSQLDB server. IMHO, the quickest is to run the following Maven command:

mvn exec:java -Dexec.mainClass="org.hsqldb.Server"

But you may prefer the old school java -cp hsqldb-XXX.jar org.hsqldb.Server ;-).

Tip! To get a GUI to check the content of the DB instance, you can run:

mvn exec:java -Dexec.mainClass="org.hsqldb.util.DatabaseManager"

Then build and launch Jetty:

mvn clean install jetty:run-exploded

Here you can see the great feature of HSQLDB, that will allow you to create, alter and delete tables on the fly (if hibernate.hbm2ddl.auto is set to create-drop), without any SQL scripts, but only thanks to HBM mapping files.

PostHeaderIcon Unable to instantiate default tuplizer… java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.

Case

On running a web application hosted on Jetty, I get the following stracktrace:

Nested in org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/classes/config/spring/beans/HibernateSessionFactory.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer]:
java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(I)V

Unlike what I immediatly thought at first glance, the problem is not induced by the Tuplizer ; the actual error is hidden at the bottom: java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.

Here are some of the dependencies:

org.hsqldb:hsqldb:jar:2.2.8:compile
org.springframework:spring:jar:2.5.6:compile
org.hibernate:hibernate:jar:3.2.7.ga:compile
javax.transaction:jta:jar:1.0.1B:compile
 |  +- asm:asm-attrs:jar:1.5.3:compile
 |  \- asm:asm:jar:1.5.3:compile

Fix

Main fix

The case is a classic problem of inherited depencencies. To fix it, you have to excluse ASM 1.5.3, and replace it with more recent version. In the pom.xml, you would then have:

    <properties>
        <spring.version>3.1.0.RELEASE</spring.version>
        <hibernate.version>3.2.7.ga</hibernate.version>
        <asm.version>3.1</asm.version>
    </properties>
...
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate</artifactId>
            <version>${hibernate.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>asm</groupId>
                    <artifactId>asm</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>asm</groupId>
                    <artifactId>asm-attrs</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>asm</groupId>
            <artifactId>asm</artifactId>
            <version>${asm.version}</version>
        </dependency>

Other improvements

I took the opportunity to upgrade Spring 2.5 to Spring 3.1 (cf the properties above).
Besides, I modified the *.hbm.xml files to use object types, rather than primary types, eg replacing:

<id name="jonathanId" type="long">

with:

<id name="jonathanId" type="java.lang.Long">