Preface
NoSQL databases provide different data modeling and performance characteristics compared to Relational Databases, yet the necessity to map between the Database specific format and Java objects is still prevalent. Hibernate is an Object/Relational Mapping solution for Java environments. The term Object/Relational Mapping refers to the technique of mapping data from an object model representation to a relational data model representation (and vice versa).
Hibernate NoSQL is an extension to Hibernate ORM, providing a similar developer experience to NoSQL Database users. It takes care of the mapping from Java classes to documents/graphs/tables (and from Java data types to datastore data types), but also provides data query and retrieval facilities. It can significantly reduce development time otherwise spent with manual data handling in the various proprietary query languages and specialized drivers. Hibernate NoSQL’s design goal, similar to Hibernate ORM’s, is to relieve the developer from 95% of common data persistence-related programming tasks by eliminating the need for manual, hand-crafted data processing. However, unlike many other persistence solutions, Hibernate NoSQL does not hide the power of the native query language and driver from you.
Hibernate NoSQL may not be the best solution for data-centric applications that use highly specialized driver/datastore features to implement the business logic, it is most useful with object-oriented domain models and business logic in the Java-based middle-tier. However, Hibernate NoSQL can certainly help you to remove or encapsulate vendor-specific query and driver code and will help with the common task of result set translation from the native driver representation to a graph of objects.
Getting Started
While a strong background in SQL is not required to use Hibernate, a basic understanding of its concepts is useful - especially the principles of data modeling. Understanding the basics of transactions and design patterns such as Unit of Work are important as well.
Get Involved
-
Use Hibernate NoSQL and report any bugs or issues you find. See Issue Tracker for details.
-
Try your hand at fixing some bugs or implementing enhancements. Again, see Issue Tracker.
-
Engage with the community using the methods listed in the Community section.
-
Help improve this documentation. Contact us on the developer mailing list or Zulip if you have interest.
-
Spread the word. Let the rest of your organization know about the benefits of Hibernate.
1. Compatibility
1.1. Dependencies
Hibernate NoSQL 1.0.0.Alpha1 requires the following dependencies (among others):
Version |
|
|---|---|
Java Runtime |
17 or 21 |
7.4.5.Final |
|
JDBC (bundled with the Java Runtime) |
4.2 |
|
Find more information for all versions of Hibernate NoSQL on our compatibility matrix. The compatibility policy may also be of interest. |
If you get Hibernate NoSQL from Maven Central, it is recommended to import Hibernate Platform as part of your dependency management to keep all its artifact versions aligned.
- Gradle
dependencies {
implementation platform "org.hibernate.nosql:hibernate-platform:1.0.0.Alpha1"
// use the versions from the platform
implementation "org.hibernate.nosql:hibernate-nosql-core"
// Use a NoSQL dialect of your choice
implementation "org.hibernate.nosql:hibernate-neo4j"
implementation "jakarta.transaction:jakarta.transaction-api"
}
- Maven
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.hibernate.nosql</groupId>
<artifactId>hibernate-platform</artifactId>
<version>1.0.0.Alpha1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- use the versions from the platform -->
<dependencies>
<dependency>
<groupId>org.hibernate.nosql</groupId>
<artifactId>hibernate-nosql-core</artifactId>
</dependency>
<!-- Use a NoSQL dialect of your choice -->
<dependency>
<groupId>org.hibernate.nosql</groupId>
<artifactId>hibernate-neo4j</artifactId>
</dependency>
<dependency>
<groupId>jakarta.transaction</groupId>
<artifactId>jakarta.transaction-api</artifactId>
</dependency>
</dependencies>
1.2. Database
Hibernate NoSQL 1.0.0.Alpha1’s compatibility with a given database and version depends on the dialect being used.
Refer to the Dialects guide for details about both dialects and supported databases.
2. Overview
2.1. Modules
Hibernate NoSQL is split into
-
hibernate-nosql-core - Implementation of the Jakarta JNoSQL specification
-
hibernate-platform - The platform or bill-of-materials (BOM) module which can be used to align versions of the Hibernate modules along with the versions of its libraries
-
hibernate-<nosql-database> - A module per supported NoSQL database, enabling the use of Hibernate ORM APIs with that database
2.2. Relation to Hibernate ORM and JDBC
The various Hibernate NoSQL database modules make use of Hibernate ORM SPIs, like Dialect, to implement support for the respective NoSQL database.
Sometimes these modules also come with a minimal JDBC driver implementation, that delegates work to an underlying native driver,
which is supported by the NoSQL database vendor directly.
The goal of these JDBC driver implementations is not to fully implement the JDBC specification, but rather implement enough aspects, such that Hibernate ORM can reasonably work with them. The JDBC drivers that come with these modules are only intended to be used with Hibernate ORM and not directly by an application, since the drivers will require passing the native query language, as well as special parameter markers or use a certain serialization format. Similarly, binding/extraction of parameters/results for various data types is only implemented for the purposes of Hibernate ORM.
3. NoSQL data stores
3.1. Milvus
Milvus is a very targeted database, with its main focus on vector search. The hibernate-milvus artifact strives to
support CRUD functionality, basic queries and common HQL/Criteria vector search queries.
The hibernate-milvus module implements the JDBC driver API on top of the native driver io.milvus:milvus-sdk-java
via the class org.hibernate.milvus.jdbc.internal.MilvusDriver.
The JDBC URL format is jdbc:milvus://<host>[:<port>]/<database>[?queryParam1=value1[&queryParam2=value2]*] and supports
the following query parameters:
-
secure-trueorfalse(default) indicating whether to usehttpsorhttpto connect to the database host
The short name Milvus will automatically resolve to the dialect class org.hibernate.milvus.MilvusDialect when
configured for the hibernate.dialect configuration property, but note that the MilvusDialect will be automatically
selected through the DialectResolver contract, unless hibernate.boot.allow_jdbc_metadata_access is set to false.
3.1.1. Features and considerations
Schema generation support
Schema generation is supported, but Milvus requires that a collection (table) contains at least one vector field
(non-null until version 3.0) and that an index exists, as well as that the collection is "loaded".
This artifact will automatically add a vector field named embedding, if no vector field was found on an entity mapping
and fill it with a [0, 0] vector on insert. It will also create a COSINE vector index automatically and load the
collection via the schema generation (hbm2ddl).
Indexes can also be declared via the Jakarta Persistence @Table(indexes) annotation and will create automatic indexes
or vector indexes, depending on the type of the column/field.
Declaring an index for a vector field, will create a vector index. To specify the metric or other index parameters,
provide the options member and give a comma-separated list of assignment-operator-separated key-value pairs
e.g. @Index( name = "VectorEntity_ip", columnList = "the_ip_vector", options = "metric=ip").
Supported values for metric are defined via the io.milvus.v2.common.IndexParam.MetricType enumeration,
e.g. l2, ip, cosine, hamming, jaccard etc.
The valid values for the type option are defined via the io.milvus.v2.common.IndexParam.IndexType enumeration,
e.g. flat, ivf_flat, hnsw, diskann etc.
Consult the vendor documentation for an explanation of the available
options per type.
Vector distance transformation
Plain vector distance function usage in the select clause and order by clause are allowed and transformed appropriately.
Ordering by distance is only supported in the natural order of the distance metric that means "closer".
The inner_product metric natural order is descending, whereas all the other metrics require ascending order.
Driver requests require that vector distance filtering happens through dedicated values radius and range_filter.
In order to support that, the dialect analyzes the predicate and tries to hoist the vector distance filtering as a top-level predicate.
Therefore, it’s important to ensure the vector distance restriction can be hoisted i.e. the following is illegal x is null or cosine_distance(…) < 1.
Translation between the vector distance and the native driver score is done automatically, but beware that Milvus only has 32-bit float precision for the vector distance/score when trying to compare distance values and the transformations between distance and score representation can therefore lead to some inaccuracies when working with exact values. If exact values are used, try to round, truncate or simply subtract a slight error margin from the float value.
Note that due to the nature of the fixed comparison operators that are applied for radius and range_filter, the
driver might apply slight offsets (Float.MIN_VALUE) to filter values to emulate a greater than (>) operator when the
natural operator is greater or equal (>=) and so on.
Data type transformation
The native Milvus driver does not support transferring 8- or 16-bit integers, as well as 32-bit floats.
When widening a 32-bit float to a 64-bit double, there is a chance that the string representation of the two values is
different, which is why this driver chose to widen 32-bit floats by doing Double.parseDouble( Float.toString( floatValue ) ) instead.
Keep this in mind when working with floating point comparisons, like vector distance comparisons.
Id list transformation
Driver requests require that primary key based filtering happens through a dedicated list of values.
In order to support that, the dialect analyzes the predicate and tries to hoist the id filtering as a top-level predicate.
Therefore, it’s important to ensure the id restriction can be hoisted i.e. the following is illegal x is null or id in :list.
3.1.2. Limitations
Transaction support
Milvus does NOT support transactions, so better ensure that every interaction that you do with your database through Hibernate ORM APIs is idempotent.
Native query support
Milvus does NOT have a native query language. Therefore, the native queries that are passed to the JDBC layer are
a String serialized form of the request object, to be passed to the native driver. Parsing and serialization is done
with org.hibernate.milvus.jdbc.MilvusJsonHelper, which you can use to construct custom native queries.
Limited query support
Milvus lacks many basic querying features. The following is a non-exhaustive list of HQL/Criteria features that DON’T work
-
CTEs (
withclause) -
Select statements in
fromclause -
Set operations (
union,except,intersect) -
Insert-Select statements
-
Select statement with
distinctclause -
selectclause with anything but path or vector distance items -
Joins
-
Subqueries
-
havingclause -
group byclause with more than one item or non-path item -
order byclause with anything but natural vector distance order (until Milvus 3.0) -
fetchclause with anything butROWS ONLY -
updatestatement withwhereclause other than single primary key restriction -
Anything involving SQL fragments e.g.
@ColumnTransformer,@Formula,@JoinFormula,@GeneratedColumn,@Filter,@FilterJoinTable,@SQLRestriction,@SQLJoinTableRestriction,@SQLOrder -
Anything involving SQL statements e.g.
@NamedNativeQuery,@SQLSelect,SQLDelete,@SQLInsert,@SQLUpdate -
@Inheritance(strategy)other thanSINGLE_TABLE -
Locking (optimistic and pessimistic) as well as
@Version -
Case insensitive
likepredicate -
Not equal (
<>/!=) oris distinct fromoperator for vector distance -
No or multiple
fromclause items -
Functions anywhere but in the
whereclause, except vector distance and aggregate functions inselectclause -
Most functions, except
-
mod -
power -
json_array -
json_value -
json_query -
json_exists -
array -
array_list -
array_length -
array_get -
array_contains -
array_includes -
array_intersects -
<metric>_distancei.e. vector distance functions -
No support for
binary,varbinaryandblobdata types
-
3.2. Neo4j
Neo4j is a graph database with lots of functionality. The hibernate-neo4j artifact strives to
support CRUD functionality and many kinds of search queries and functions.
The hibernate-neo4j is designed to work with the official JDBC driver org.neo4j:neo4j-jdbc-full-bundle
via the class org.neo4j.jdbc.Neo4jDriver.
The JDBC URL format is jdbc:neo4j://<host>[:<port>]/<database>[?queryParam1=value1[&queryParam2=value2]*].
For further details, consult the driver documentation of the vendor.
The short name Neo4j will automatically resolve to the dialect class org.hibernate.neo4j.Neo4jDialect when
configured for the hibernate.dialect configuration property, but note that the Neo4jDialect will be automatically
selected through the DialectResolver contract, unless hibernate.boot.allow_jdbc_metadata_access is set to false.
3.2.1. Features and considerations
Schema generation support
Schema generation is supported and constraints are emitted, depending on database support, since not null constraints are only supported in the Neo4j enterprise edition.
Cypher as native query language
This dialect renders Cypher queries instead of relying on the SQL translation layer of the Neo4j JDBC driver,
which means that SQL fragments (e.g. @ColumnTransformer, @Formula, @JoinFormula, @GeneratedColumn, @Filter, @FilterJoinTable, @SQLRestriction, @SQLJoinTableRestriction, @SQLOrder)
need to be valid Cypher fragments.
4. Credits
The full list of contributors to Hibernate NoSQL can be found on the GitHub repository.
The following contributors were involved in this documentation:
-
Christian Beikov
References
-
[PoEAA] Martin Fowler. Patterns of Enterprise Application Architecture. Addison-Wesley Professional. 2002.
-
[JPwH] Christian Bauer & Gavin King. Java Persistence with Hibernate, Second Edition. Manning Publications Co. 2015.