# Java Schema Definition

> Java applications define the database classes to be managed in the eXtremeDB runtime using native Java class syntax applying special annotations.

> For example, the following code snippet would define a database with two classes Department and Employee:

>         @Persistent()
>         class Department
>         {
>             @Indexable(Type = Database.IndexType.BTree, Unique = true)
>             public String code;
>             public String name;
>             @Indexable(Type = Database.IndexType.Hashtable, Unique = true)
>             public int dept_no;
>         }

>         @Index("byDept_EmployeeName", Keys = new string[] { "dept_no", "name" }, Unique = false)

>         @Persistent()
>         class Employee
>         {
>             @Indexable(Type = Database.IndexType.BTree, Unique = true)
>             public String  name;
>             public int  dept_no;
>         }

> Note that the annotations `@Persistent()`, `@Indexable()`and `@Index()` are used to specify the classes and indexes to be generated and maintained in the database.

> ## eXtremeDB JNI Database Annotations

> The annotations that are recognized as eXtremeDB database specifications are as follows:

> - `Persistent`
>   Class annotation: Marks this class as “stored in the database” and optionally provides some attributes of this class;

>   `Persistent(autoid=true)` | Creates an `autoid` index
>   `Persistent(list=true)` | Creates a list index
>   `Persistent(large=true)` | Declares the standard storage model (default)
>   `Persistent(compact=true)` | Declares the compact storage model
>   `Persistent(inmemory=true)` | Declares this class as in-memory (default)
>   `Persistent(disk=true)` | Declares this class as disk-based (i.e on persistent storage media)
>   `Persistent(local=true)` | Declares this class as `local` for eXtremeDB High Availability partial replication

> - `Index`
>   Class annotation: Defines a compound (multi-field) index; possible properties are:

>   name="indexName" | Identifies this index
>   keys={Key(“field1”) [, Key(“field2”) …] } | List of key fields
>   unique=true | Creates a b-tree index (the default), true enforces uniqueness; if `false` allows duplicates
>   thick=true | Optimized for a large number of duplicates
>   descending=true | Indexes are `ascending` by default
>   initSize=N | For hash indexes; `N` is the initial size of the hash table
>   type=Database.IndexType.BTree | Possible `Database.IndexType` values are: BTree - Creates a `tree` index (the default) Hashtable - Creates a `hash` index Patricia - Creates a `patricia` index RTree - Creates an `rtree` index RTreeOfPoint - Creates an `rtree` index KDTree - Creates a `kdtree` index Trigram - Creates a `trigram` index

>   for example:

>           @Index(name="byName", keys={ Key("lastName"), Key("firstName") }, unique=true )

>           class Employee
>           {
>               String  firstName;
>               String  lastName;
>               Address address;
>               long    salary;
>           }

> - `Indexable`
>   Field annotation: Specifies an index on the following field. The index will have the same name as the field. With the exception of `name` and `keys` properties, the possible properties are the same as for class attribute `Index` (above).
>   for example:

>           class Obj
>           {
>               @Indexable(Type=Database.IndexType.BTree, Unique=true)
>               public int value;
>           }

> - `Encoding`
>   Field annotation: Specifies the encoding of string fields. Can be any valid encoding supported by the Java runtime. `UTF-8` is the default. Examples:

>           @Encoding("UTF-16")
>           String s1;
>           @Encoding("ASCII")
>           String s2;

> - `Blob`
>   Field annotation: Uses eXtremeDB BLOB type for storing a byte array; for example:

>           @Blob
>           byte photo[];

> - `Dimension`
>   Field annotation: Specifies the dimension for fixed size arrays (char, scalar) An array without a dimension will be treated as a `vector` (dynamic array).
>   Example:

>           @Dimension(8)
>           String prefix;

> - `Numeric`
>   Field annotation: Specifies the width and precision for decimal fields.
>   Example:

>           @Numeric(12,3)

>           decimal d;
>           // Equivalent to decimal<12,3> d;

> - `Binary`
>   Field annotation: Specifies a fixed length Binary field.
>   Example:

>           @Binary(100)

>           byte[] dim100_binary;
>           // A Binary array of 100 bytes

> - `Varbinary`
>   Field annotation: Specifies a variable length Binary field.
>   Example:

>           @Varbinary

>           byte[] var_binary;
>           // A Binary vector (dynamic array)

> - `Nullable`
>   Field annotation: Specifies that this field can be null.
>   Example:

>           @Nullable

>           bool isALive; // Explicitly declared nullable field

> - `OptionalStruct`
>   Field annotation: Defines a structure field as optional; for example:

>           @OptionalStruct
>           NestedStruct opt_nested; // optional NestedStruct opt_nested;

> - `References`
>   Field annotation: Used to declare a field of type `ref` which refers to a Class in the schema; for example:

>           @References(ClassA.class)]
>           long a;

> - `Sequence`
>   Field annotation: Used to declare a field of type `sequence`; for example:

>           @Sequence(type=Sequence.Type.UInt8)
>           OrderedSequence stamp;

>   Note that when an `OrderedSequence` is declared the default order is `Ascending`. The default can be overwritten explicitly:

>           @Sequence(order=Sequence.Order.Descending, type=Sequence.Type.UInt8)
>           OrderedSequence stamp;