Persistence Model

An entity is a lightweight persistence domain object. The persistent state of an entity is represented through persistent fields using Java Beans / Plain Old Java Objects (POJOs).

The Spring Data Framework supports the persistence of entities to Oracle NoSQL Database tables. An entity is mapped to a table. The ID field in that entity is mapped to the primary key column of that table. All other fields in the entity are mapped to a JSON column of that table. Each instance of the entity will be stored as a single row in that table. The value of the ID field in that instance will be stored as the primary key value of that row. The values of all other fields (including other objects) (see JSON Column) in that instance will be serialized and stored as values in the JSON column of that row. Effectively, the table will always have only two columns: a primary key column and a JSON column.

If a persistent POJO has a reference to another persistent POJO (nested objects) that maps to a different table, the Spring Data Framework will not serialize objects to multiple tables. Instead, all the nested objects will be serialized and stored as values in the JSON column. For more information on JSON Column mappings, see JSON Column.

The following is the syntax of an entity with @NosqlTable and @NosqlId annotations. In the example below, the Student class with the @NosqlTable annotation will be mapped to a table named Student in the Oracle NoSQL Database. The ID field with the @NosqlId annotation will be the primary key field in the Student table. The firstName and lastName fields will be mapped to a single JSON field named kv_json_ in the Student table.

When retrieving entries from the repository the driver needs to instantiate the entity classes. These classes need to have a default constructor or an empty constructor that is public or package protected.

Note:

The classes may have other constructors too.
/*The @NosqlTable annotation specifies that 
this class will be mapped to an Oracle NoSQL Database table.*/
@NosqlTable
public class Student {
    //The @NosqlId annotation specifies that this field will act as the ID field.
    @NosqlId
    public long ID;
  
    public String firstName;
    public String lastName;
  
    public Student() {}
}

Table Name

By default, the entity simple class name is used for the table name. You can provide a different table name using the @NosqlTable annotation. The @NosqlTable annotation enables you to define additional configuration parameters such as table name and timeout.

For example, an entity named Student will be persisted in a table named Student. If you want to persist an entity named Student in a table named Learner, you can achieve that using the @NosqlTable annotation.

If the @NosqlTable annotation is specified, then the following configuration could be provided.

Table 1-1 Attributes in NosqlTable Annotation

Parameter Type Ignored/ Optional/ Required in Oracle NoSQL Database Ingnored/ Optional/ Required in Oracle NoSQL Database Cloud Service Default Description
tableName String Optional Optional empty

Specifies the name of the table, simple or namespace-qualified form.

If empty, then the entity class name will be used.

For more information on the namespace, see Namespace Management in the SQL Reference Guide.

In the Oracle NoSQL Database Cloud Service, the namespace part, if provided, is used as the compartment name. For more information on using compartments, see About Compartments in the Using Oracle NoSQL Database Cloud Service.

autoCreate boolean Optional Optional true

Specifies if the table should be created if it does not exist.

Note:

The Spring Data Framework looks for the repositories used in the application in the init phase. If the table does not exist, and if the @NosqlTable annotation has the autoCreate as true, then the table will be created in the init phase.
readUnits int Ignored Required -1

Specifies the maximum read throughput to be used if the table is to be created.

For more information on readUnits, see Service Metrics in the Using Oracle NoSQL Database Cloud Service.

Note:

In Oracle NoSQL Database Cloud Service, the readUnits parameter should be set to a value greater than 0 else it will return an error.
writeUnits int Ignored Required -1

Specifies the maximum write throughput to be used if the table is to be created.

For more information on writeUnits, see Service Metrics in the Using Oracle NoSQL Database Cloud Service.

Note:

In Oracle NoSQL Database Cloud Service, the writeUnits parameter should be set to a value greater than 0 else it will return an error.
storageGB int Ingored Required -1

Specifies the maximum amount of storage, in gigabytes, allowed for the table, if the table is to be created.

For more information on storageGB, see Service Metrics in the Using Oracle NoSQL Database Cloud Service.

Note:

In Oracle NoSQL Database Cloud Service, the storageGB parameter should be set to a value greater than 0 else it will return an error.
timeout int Optional Optional 0

Specifies the maximum time length, in milliseconds, that the operations are allowed to take before a timeout exception is thrown.

If the value for timeout is not set then the timeout set in NoSQLHandleConfig class is used. For information on getting the timeout from NoSQLHandleConfig class using getTableRequestTimeout() method, see NoSQLHandleConfig in the Java SDK API Reference.

The timeout value can also be changed using NosqlRepository.setTimeout(int) method. For more information, see setTimeout in the SDK for Spring Data API Reference.

consistency String Optional Optional EVENTUAL

Specifies the consistency used for read operations.

Valid values are based on oracle.nosql.driver.Consistency are EVENTUAL and ABSOLUTE . See Consistency in the Java SDK API Reference.

Note:

This is the default for all read operations. It can be overridden by using NosqlRepository.setConsistency(String). For more information, see setConsistency in the SDK for Spring Data API Reference.

Primary Key

The table requires a primary key. The field named ID in the entity will be used as the primary key. You can select a different field in the entity (a field with a different name other than ID) to designate as the primary key using the @NosqlId annotation or the @id annotation.

When an ID field is mapped to a primary key column, the Spring Data Framework will automatically assign the corresponding data type to that field before storing them in the table. The following is a list of data type mappings between a Java type and an Oracle NoSQL Database type for the ID field.

The Java types that are provided in the following table are the only valid data types that can be used for a primary key.

Table 1-2 Mapping Between Java and Oracle NoSQL Database Types

Java Type Oracle NoSQL Database Type

java.lang.String

STRING

int

java.lang.Integer

INTEGER

long

java.lang.Long

LONG

double

java.lang.Double

float

java.lang.Float

DOUBLE

Note:

double, java.lang.Double, float, and java.lang.Float can be a primary key but it's not a valid generated=true type

Note:

Since FLOAT in Oracle NoSQL Database type is not explicitly used in NoSQL SDK for Java, the Java float and java.lang.Float are mapped to the DOUBLE type.

java.math.BigDecimal

java.math.BigInteger

NUMBER

boolean

java.lang.Boolean

BOOLEAN

java.util.Date

java.sql.Timestamp

java.time.Instant

TIMESTAMP (P)

The Spring Data Framework deduces the primary key using the following rules:
  • @NosqlId annotation: If @NosqlId annotation is used on a field with a valid data type for the primary key, then that field is considered as the primary key. If @NosqlId is used on a field of a type other than a valid data type for the primary key, an error is raised. For more information, see NosqlId in the SDK for Spring Data API Reference.
  • @org.springframework.data.annotation.Id annotation: If @org.springframework.data.annotation.Id field annotation is used on a field with a valid data type for the primary key, then that field is considered as the primary key. If @org.springframework.data.annotation.Id is used on a field of a type other than a valid data type for the primary key, an error is raised.
  • Not specified: If none of the above two annotations are specified, then the Spring Data Framework will use the field named ID as the primary key.
An error is raised if:
  • No @NosqlId annotation or @org.springframework.data.annotation.Id annotation or ID field is found in the entity, as no primary key field can be inferred.
  • Two or more of @NosqlId or @org.springframework.data.annotation.Id annotated fields are used in the entity, as multiple primary key fields can be inferred.

Note:

The name of the fields that take the @NosqlId or @org.springframework.data.annotation.Id annotations must not be named kv_json_. It is because the second column of the table created by the Spring Data Framework will be named as kv_json_ and will be a JSON column where all attributes in the persistent entity that are not listed as primary key attributes will be stored.

The @NosqlId field annotation can take the following additional configuration:

Table 1-3 Attributes in NosqlId Annotation

Parameter Type Optional/Required Default Description
generated boolean Optional false

Specifies if the ID is auto-generated or not.

  • If true, then it is defined as auto-generated by the program.
    • If int/Integer, long/Long, BigInteger or BigDecimal, then GENERATED ALWAYS as IDENTITY is used.
    • If String, then "String as UUID GENERATED BY DEFAULT" is used.

      Note:

      Currently not available in the Oracle NoSQL Database Cloud Service.
  • If false, then the value must be managed by your application.

Note:

Composite primary keys are not supported.

JSON Column

All other fields in the entity other than the primary key field will be converted into a NoSQL JSON value with the following rules:

  • The Java scalar values will be converted to NoSQL JSON atomic values.
  • The Java collections and array structures will be converted to a NoSQL JSON array.
  • The Java non-scalar values will be recursively converted to NoSQL JSON objects.
  • The Java null values will be converted to NoSQL JSON NULL values.
  • The complex values will be converted to NoSQL JSON objects according to the following table.

Table 1-4 Mapping Between Java and NoSQL JSON Types

Java Type Representation within Oracle NoSQL Database JSON Datatype

java.lang.String

STRING

int

java.lang.Integer

INTEGER

long

java.lang.Long

LONG

double

java.lang.Double

float

java.lang.Float

DOUBLE

Note:

Since FLOAT in Oracle NoSQL Database type is not explicitly used in NoSQL SDK for Java, Java float, and java.lang.Float are mapped to the DOUBLE type.

java.math.BigDecimal

java.math.BigInteger

NUMBER

boolean

java.lang.Boolean

BOOLEAN

byte[]

STRING - a binary base64-encoded representation.

java.util.Date

java.sql.Timestamp

java.time.Instant

STRING - an ISO-8601 UTC timestamp encoded representation.

org.springframework.data.geo.Point

GeoJson Point

For more information on GeoJson Data, see About GeoJson Data in the SQL Reference Guide.

org.springframework.data.geo.Polygon

GeoJson Polygon

For more information on GeoJson Data, see About GeoJson Data in the SQL Reference Guide .

Note:

Polygons must conform to the following rules to be well-formed, otherwise they will be ignored when used in queries.
  1. A linear ring is a closed LineString with four or more positions.
  2. The first and last positions are equivalent, and they must contain identical values.
  3. A linear ring is either the boundary of a surface or the boundary of a hole in a surface.
  4. A linear ring must follow the right-hand rule for the area it bounds, that is, for exterior rings, their positions must be ordered counterclockwise, and for holes, their position must be ordered clockwise.

Before inserting new polygons in the table, the geo_is_geometry() function can be used for verification. If polygon data is indexed an error will be raised if for some row the value of the index path is not valid, unless that value is NULL, json null, or EMPTY.

java.util.ArrayList

java.util.Collection

java.util.List

java.util.AbstractList

java.util.HashSet

java.util.Set

java.util.AbstractSet

java.util.TreeSet

java.util.SortedSet

java.util.NavigableSet

java.util.Array []

ARRAY(JSON)

Note:

  • For fields of type java.util.Collection, java.util.List, java.util.AbstractList, and java.util.ArrayList, an java.util.ArrayList object is instantiated.
  • For fields of type java.util.Set, java.util.AbstractSet, and java.util.HashSet, a java.util.HashSet object is instantiated.
  • And for fields of type java.util.SortedSet, java.util.NavigableSet, and java.util.TreeSet, a java.util.TreeSet object is instantiated.

POJO<f1 T1, f2 T2...>

MAP(JSON)

java enum types

STRING

Note:

Java data structures that contain cycles are neither supported nor detected. That is, if the entity object is traversed from the root down the fields and encounters the same object twice it becomes a cycle.