Some datastores have a well-defined structure and when persisting/retrieving from these datastores
you have to have this
schema
in place. DataNucleus provides various controls for creation
of any necessary schema components. This creation can be performed as follows

One off task before running your application using SchemaTool.
This is the recommended option since it separates schema from operation.

At runtime, using some persistence properties.

The thing to remember when using DataNucleus is that
the schema is under your control
.
DataNucleus does not impose anything on you as such, and you have the power to turn on/off all
schema components.
Some Java persistence tools add various types of information to the tables for persisted
classes, such as special columns, or meta information. DataNucleus is very unobtrusive as far
as the datastore schema is concerned. It minimises the addition of any implementation artifacts
to the datastore, and adds
nothing
(other than any datastore identities, and version
columns where requested) to any schema tables.

DataNucleus can generate the schema for the developer as it encounters classes in the
persistence process. Alternatively you can use the SchemaTool
application before starting your application.

If you want to create the schema ("tables"+"columns"+"constraints") during the persistence
process, the property
datanucleus.autoCreateSchema
provides a way of telling
DataNucleus to do this. It's a shortcut to setting the other 3 properties to true.
Thereafter, during calls to DataNucleus to persist classes or performs queries of persisted data,
whenever it encounters a new class to persist that it has no information about, it will use
the MetaData to check the datastore for presence of the "table", and if it doesn't exist, will
create it. In addition it will validate the correctness of the table (compared to the MetaData
for the class), and any other constraints that it requires (to manage any relationships).
If any constraints are missing it will create them.

If you wanted to only create the "tables" required, and none of the "constraints" the property
datanucleus.autoCreateTables
provides this, simply performing the tables part of the
above.

If you want to create any missing "columns" that are required, the property
datanucleus.autoCreateColumns
provides this, validating and adding any missing
columns.

If you wanted to only create the "constraints" required, and none of the "tables" the property
datanucleus.autoCreateConstraints
provides this, simply performing the "constraints"
part of the above.

If you want to keep your schema fixed (i.e don't allow any modifications at runtime) then
the property
datanucleus.fixedDatastore
should be set to
true
and this has the
effect of setting the "table"+"columns"+"constraints" autoCreate values to
false

DataNucleus can check any existing schema against what is implied by the MetaData.

The property
datanucleus.validateTables
provides a way of telling DataNucleus to
validate any tables that it needs against their current definition in the datastore. If
the user already has a schema, and want to make sure that their tables match what
DataNucleus requires (from the MetaData definition) they would set this property to
true
. This can be useful for example where you are trying to map to an existing
schema and want to verify that you've got the correct MetaData definition.

The property
datanucleus.validateColumns
provides a way of telling DataNucleus to
validate any columns of the tables that it needs against their current definition in the
datastore. If the user already has a schema, and want to make sure that their tables match
what DataNucleus requires (from the MetaData definition) they would set this property
to
true
. This will validate the precise column types and widths etc, including
defaultability/nullability settings.
Please be aware that many JDBC drivers contain bugs
that return incorrect column detail information and so having this turned off is sometimes
the only option (dependent on the JDBC driver quality).

The property
datanucleus.validateConstraints
provides a way of telling DataNucleus
to validate any constraints (primary keys, foreign keys, indexes) that it needs against
their current definition in the datastore. If the user already has a schema, and want to
make sure that their table constraints match what DataNucleus requires (from the
MetaData definition) they would set this property to
true
.

Some datastores allow access to multiple "schemas" (such as with most RDBMS).
DataNucleus will, by default, use the "default" database schema for the Connection URL and
user supplied. This may cause issues where the user has been set up and in some databases
(e.g Oracle) you want to write to a different schema (which that user has access to).
To achieve this in DataNucleus you would set the runtime properties

By default all tables are generated with columns in alphabetical order, starting with root class
fields followed by subclass fields (if present in the same table) etc. There is a JDO3.1
attribute that allows you to specify the order of columns for schema generation. This is not
present in JPA. It is achieved by specifying the metadata attribute
position
against
the column.

<column position="1"/>

Note that the values of the position start at 0, and should be specified completely for all
columns of all fields.

If your datastore is read-only (you can't add/update/delete any data in it), obviously you
could just configure your application to not perform these operations. An alternative with JDO
is to set the PersistenceManagerFactory as "read-only". You do this by setting the
persistence property
javax.jdo.option.ReadOnly
to
true
. For JPA you would set
the persistence property
datanucleus.ReadOnlyDatastore
to
true
.

From now on, whenever you perform a persistence operation that implies a change in datastore
data, the JDO operation will throw a
JDOReadOnlyException
, whereas JPA will throw a
PersistenceException
.

DataNucleus provides an additional control over the behaviour when an attempt is made to
change a read-only datastore. The default behaviour is to throw an exception. You can change this
using the persistence property
datanucleus.readOnlyDatastoreAction
with values of
"EXCEPTION" (default), and "IGNORE". "IGNORE" has the effect of simply ignoring all attempted
updates to readonly objects.

You can take this read-only control further and specify it just on specific classes. Like this