Hibernate sucks but what’s the alternatives? Java Persistance Options

Everyone seems to jump straight to hibernate and not consider alternatives and when to use each. Let’s look at this afresh. We want to create a SAAS or self-hosted app and for any modified entites to be persisted. Entites being users, teams and widgets. Imagine something like a simple github json API server where users belong to a team, users or teams may have repos etc.

Typical Operations

  • Create a user/team.
  • Get a user and the list of teams they are linked to.
  • For a given widget, check if the user has access permission.
  • Keep database updated as new columns or tables are added.

Options:

  • Hibernate – Java Class Driven. Fully mapped objects, generate schema from objects, query everything through repositories i.e. hibernate layer.
  • Hibernate Hybrid – For most save items, update items use hibernate. For some complex or optimized selects use raw SQL with automapping to JSON where possible.
    • Automap requires either creating java classes and letting Object->JSON happen
    • Manual conversion / automatic resultset conversion.
  • Raw SQL – Thin Wrapper. Create database manually. Insert / Select writing raw SQL tables. Probably use a very thin wrapper that autoconverts resultsets to JSON.
  • JOOQ – Database Driven – Based on database generate type safe java access layers.
  • Blob Storage (Async) – Literally do not run any SQL commands. Only periodically save down all java state required. I mean you could even serialize everthing to one binary file. Or serialize large chunks and store them as strings to database.

Decision Pivot Points:

  • If SQL querying not needed and no relations within or no insight into inner data = Blob
  • If many standard CRUD operations over different entities = Hibernate
  • If many customized selects = JOOQ – to provide type checking.
  • Never RawSQL. You may as well use a very thin wrapper.
  • Other options? Write your own wrapper to persistance?

Outcome for me

Unfortunately we already adopted hibernate before giving it much thought. In hindsight we should have evaluated JOOQ as we have 2-3 entities which have modified SQL queries for half the operations.

Update:2023-11-23 I tried to convert parts of code base to JOOQ. JOOQ had lots of features and great docs on versioning, locking, storing, CRUD. The main parts lacking were nicer generted POJOs with primitives for “NOT NULL” and soft deletes. Without soft deletes I can’t use it as primary persistance only for SQL queries to be type safe.

These quotes captures my worry with Hibernate:
“John, I thought we were entering a new era of software development. I thought we were doing a light-year’s jump. But, after four years, it seems like we are still dealing with all the same problems, only from a different angle. I had to learn Hibernate architecture, configuration, logging, naming strat…………….ritance mappings, replicating object between two different datastores, detached objects and automatic versioning, connection release modes, stateless session interface, taxonomy of collection persistence, cache levels, lazy or eager fetching and many, many more. Even with everything I know, it seems like we’ve failed badly. It’s a software fiasco! Ultimate failure! Disaster! Armageddon!”
“so we decided to rewrite it as plain SQL statements. What’s funny is that writing plain SQL was actually the fastest way of doing it, so we decided to do it as our last option.”


I would suggest one idea, to use Blob storage for individual entires that you don’t need to “look inside”. There’s no point converting JSON to java objects to nested entities, if you never need to access those entities within Java. Just store the blob.

One thought on “Hibernate sucks but what’s the alternatives? Java Persistance Options

  1. It actually gets worse. Hibernate/Frameworks are designed for mapping between 3 formats:
    1. Java Objects
    2. Frontend – JSON
    3. Persistance – SQL

    but they are not solving the actual problem. If you attempt to use these 3 mappings you will soon face multiple issues:

    Any entities that require access restricted by user, you will need to join user to the entity.
    If you join user, then when you return JSON all that users details will be returned.
    If you don’t join user, you can attempt to write an SQL filter to protect access but that won’t work for saving.

    Like

Leave a comment