<commit_before>[[ogm-api]]

// vim: set colorcolumn=100:

== Hibernate OGM APIs

Hibernate OGM has very few specific APIs.
For the most part, you will interact with it via either:

* the JPA APIs
* the native Hibernate ORM APIs

This chapter will only discuss the Hibernate OGM specific behaviors regarding these APIs.
If you need to learn JPA or the native Hibernate APIs,
check out http://hibernate.org/orm/documentation/[the Hibernate ORM documentation].

=== Bootstrap Hibernate OGM

We already discussed this subject earlier, have a look at <<ogm-configuration>> for all the details.

As a reminder, it basically boils down to either:

* set the right persistence provider in your `persistence.xml` file
  and create an `EntityManagerFactory` the usual way
* start via the Hibernate ORM native APIs using `StandardServiceRegistryBuilder` and `MetadataSources`
  to boot a `SessionFactory`

=== JPA and native Hibernate ORM APIs

You know of the Java Persistence and Hibernate ORM native APIs?
You are pretty much good to go.
If you need a refresher, make sure you read the http://hibernate.org/orm/documentation/[Hibernate ORM documentation].

A few things are a bit different though, let's discuss them.

Most of the `EntityManager` and `Session` contracts are supported.
Here are the few exceptions:

* `Session.createCriteria`: criteria queries are not yet supported in Hibernate OGM
* `Session.createFilter`: queries on collections are not supported yet
* `Session` 's `enableFilter`, `disableFilter` etc: query filters are not supported at the moment
* `doWork` and `doReturningWork` are not implemented as they rely on JDBC connections - see
  https://hibernate.atlassian.net/browse/OGM-694[OGM-694]
* `Session` 's stored procedure APIs are not supported
* `Session` 's natural id APIs are not yet supported
* `Session.lock` is not fully supported at this time
* `EntityManager` 's criteria query APIs are not supported
* `EntityManager` 's stored procedure APIs are not supported - see
  https://hibernate.atlassian.net/browse/OGM-695[OGM-695]
* `EntityManager.lock` is not fully supported at this time
* see <<ogm-query>> to know what is supported for JPQL and native queries

==== Accessing the `OgmSession` API

To execute NoSQL native queries, one approach is to use `OgmSession#createNativeQuery`.
You can read more about it in <<ogm-query-native>>.
But let's see how to access an `OgmSession` instance.

From JPA, use the `unwrap` method of `EntityManager`

.Get to an `OgmSession` from an `EntityManager`
====
[source, JAVA]
----
EntityManager entityManager = ...
OgmSession ogmSession = entityManager.unwrap(OgmSession.class);
NoSQLQuery query = ogmSession.createNativeQuery(...);
----
====

In the Hibernate native API case, you should already have access to an `OgmSession`.
The `OgmConfiguration` you used returns an `OgmSessionFactory`.
This factory in turns produces `OgmSession`.

.Get to an `OgmSession` with Hibernate ORM native APIs
====
[source, JAVA]
----
StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
    .applySetting( OgmProperties.ENABLED, true )
    .build();

OgmSessionFactory ogmSessionFactory = new MetadataSources( registry )
    .buildMetadata()
    .getSessionFactoryBuilder()
    .unwrap( OgmSessionFactoryBuilder.class )
    .build();
OgmSession ogmSession = ogmSessionFactory.openSession();
NoSQLQuery query = ogmSession.createNativeQuery(...);
----
====

=== On flush and transactions

Even though some underlying NoSQL datastores do not support transaction,
it is important to demarcate transaction via the Hibernate OGM APIs.
Let's see why.

Hibernate does pile up changes for as long as it can before pushing them down to the datastore.
This opens up the doors to huge optimizations (avoiding duplication, batching operations etc).
You can force changes to be sent to the datastore by calling `Session.flush` or `EntityManager.flush`.
In some situations - for example before some queries are executed -, Hibernate will flush automatically.
It will also flush when the transaction demarcation happens (whether there is a real transaction or not).

The best approach is to always demarcate the transaction as shown below.
This avoids the needs to manually call flush and will offer future opportunities for Hibernate OGM.

.Explicitly demarcating transactions
====
Here is how you do outside of a JTA environment.

[source, JAVA]
----<commit_msg>OGM-1229 Update the documentation after the removal of NoSQLQuery<commit_after>[[ogm-api]]

// vim: set colorcolumn=100:

== Hibernate OGM APIs

Hibernate OGM has very few specific APIs.
For the most part, you will interact with it via either:

* the JPA APIs
* the native Hibernate ORM APIs

This chapter will only discuss the Hibernate OGM specific behaviors regarding these APIs.
If you need to learn JPA or the native Hibernate APIs,
check out http://hibernate.org/orm/documentation/[the Hibernate ORM documentation].

=== Bootstrap Hibernate OGM

We already discussed this subject earlier, have a look at <<ogm-configuration>> for all the details.

As a reminder, it basically boils down to either:

* set the right persistence provider in your `persistence.xml` file
  and create an `EntityManagerFactory` the usual way
* start via the Hibernate ORM native APIs using `StandardServiceRegistryBuilder` and `MetadataSources`
  to boot a `SessionFactory`

=== JPA and native Hibernate ORM APIs

You know of the Java Persistence and Hibernate ORM native APIs?
You are pretty much good to go.
If you need a refresher, make sure you read the http://hibernate.org/orm/documentation/[Hibernate ORM documentation].

A few things are a bit different though, let's discuss them.

Most of the `EntityManager` and `Session` contracts are supported.
Here are the few exceptions:

* `Session.createCriteria`: criteria queries are not yet supported in Hibernate OGM
* `Session.createFilter`: queries on collections are not supported yet
* `Session` 's `enableFilter`, `disableFilter` etc: query filters are not supported at the moment
* `doWork` and `doReturningWork` are not implemented as they rely on JDBC connections - see
  https://hibernate.atlassian.net/browse/OGM-694[OGM-694]
* `Session` 's stored procedure APIs are not supported
* `Session` 's natural id APIs are not yet supported
* `Session.lock` is not fully supported at this time
* `EntityManager` 's criteria query APIs are not supported
* `EntityManager` 's stored procedure APIs are not supported - see
  https://hibernate.atlassian.net/browse/OGM-695[OGM-695]
* `EntityManager.lock` is not fully supported at this time
* see <<ogm-query>> to know what is supported for JPQL and native queries

==== Accessing the `OgmSession` API

To execute NoSQL native queries, one approach is to use `OgmSession#createNativeQuery`.
You can read more about it in <<ogm-query-native>>.
But let's see how to access an `OgmSession` instance.

From JPA, use the `unwrap` method of `EntityManager`

.Get to an `OgmSession` from an `EntityManager`
====
[source, JAVA]
----
EntityManager entityManager = ...
OgmSession ogmSession = entityManager.unwrap(OgmSession.class);
NativeQuery query = ogmSession.createNativeQuery(...);
----
====

In the Hibernate native API case, you should already have access to an `OgmSession`.
The `OgmConfiguration` you used returns an `OgmSessionFactory`.
This factory in turns produces `OgmSession`.

.Get to an `OgmSession` with Hibernate ORM native APIs
====
[source, JAVA]
----
StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
    .applySetting( OgmProperties.ENABLED, true )
    .build();

OgmSessionFactory ogmSessionFactory = new MetadataSources( registry )
    .buildMetadata()
    .getSessionFactoryBuilder()
    .unwrap( OgmSessionFactoryBuilder.class )
    .build();
OgmSession ogmSession = ogmSessionFactory.openSession();
NativeQuery query = ogmSession.createNativeQuery(...);
----
====

=== On flush and transactions

Even though some underlying NoSQL datastores do not support transaction,
it is important to demarcate transaction via the Hibernate OGM APIs.
Let's see why.

Hibernate does pile up changes for as long as it can before pushing them down to the datastore.
This opens up the doors to huge optimizations (avoiding duplication, batching operations etc).
You can force changes to be sent to the datastore by calling `Session.flush` or `EntityManager.flush`.
In some situations - for example before some queries are executed -, Hibernate will flush automatically.
It will also flush when the transaction demarcation happens (whether there is a real transaction or not).

The best approach is to always demarcate the transaction as shown below.
This avoids the needs to manually call flush and will offer future opportunities for Hibernate OGM.

.Explicitly demarcating transactions
====
Here is how you do outside of a JTA environment.

[source, JAVA]
----
{'fraction_non_alphanumeric': 0.07814256802338655, 'fraction_numerical': 0.0038228018889138746, 'mean_word_length': 4.687340153452685, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '414944', 'n_tokens_mistral': 2527, 'n_tokens_neox': 2362, 'n_words': 1124}