Class Permazen
- java.lang.Object
-
- io.permazen.Permazen
-
public class Permazen extends Object
Permazen Java persistence layer.Permazen is a Java persistence solution built on three layers of abstraction:
- At the bottom is a simple Key/Value Layer represented by
KVDatabase
. Transactions are supported at this layer and are accessed viaKVTransaction
. There are several availableKVDatabase
implementations, including "wrappers" for several third party key/value stores. - On top of that sits the Core API Layer, which provides a rigourous "object database" abstraction on top of
a
KVDatabase
. It supports simple fields of any Java type that can be (de)serialized to/from abyte[]
array, as well as list, set, and map complex fields, tightly controlled schema versioning, simple and composite indexes, and lifecycle and change notifications. It is not Java-specific or explicitly object-oriented: an "object" at this layer is just a structure with defined fields. The core API layer may be accessed through theDatabase
andTransaction
classes. - The Java Layer is a Java-centric, object-oriented persistence layer for Java applications.
It sits on top of the core API layer and provides a fully "Java" view of the underlying data
where all data access is through user-supplied Java model classes. All schema definition and listeners are specified
through Java annotations. Incremental JSR 303 validation is supported.
The
Permazen
class represents an instance of this top layer database, andJTransaction
represents the corresonding transactions.
User-provided Java model classes define database fields by declaring abstract Java bean methods.
Permazen
generates concrete subclasses of the user-provided abstract model classes at runtime. These runtime classes implement the Java bean methods as well as theJObject
interface. Instances of these classes are always associated with a specificJTransaction
, and all of their database state derives from that the underlying key/valueKVTransaction
.All Java model class instances have a unique
ObjId
which represents database identity.Permazen
guarantees that at most one Java instance will exist for any givenJTransaction
andObjId
. Instance creation, index queries, and certain other database-related tasks are initiated using aJTransaction
.Normal database transactions are created via
createTransaction()
. "Snapshot" transactions are purely in-memory transactions that are detached from the database and may persist indefinitely; their purpose is to hold a snapshot of some (user-defined) portion of the database content for use outside of a regular transaction. Otherwise, they function like normal transactions, with support for index queries, listener callbacks, etc. SeeJTransaction.createSnapshotTransaction()
,JTransaction.getSnapshotTransaction()
,JObject.copyOut()
, andJObject.copyIn()
.Instances of this class are usually created using a
PermazenFactory
. - At the bottom is a simple Key/Value Layer represented by
-
-
Field Summary
Fields Modifier and Type Field Description static String
GENERATED_CLASS_NAME_SUFFIX
The suffix that is appended to Java model class names to get the corresponding Permazen generated class name.
-
Constructor Summary
Constructors Constructor Description Permazen(Database database, int version, StorageIdGenerator storageIdGenerator, Iterable<? extends Class<?>> classes)
Primary constructor.Permazen(Class<?>... classes)
Create an instance using an initially empty, in-memorySimpleKVDatabase
.Permazen(Iterable<? extends Class<?>> classes)
Create an instance using an initially empty, in-memorySimpleKVDatabase
.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method Description SnapshotJTransaction
createSnapshotTransaction(KVStore kvstore, boolean allowNewSchema, ValidationMode validationMode)
Create a newSnapshotJTransaction
based on the provided key/value store.SnapshotJTransaction
createSnapshotTransaction(ValidationMode validationMode)
Create a new, emptySnapshotJTransaction
backed by aNavigableMapKVStore
.JTransaction
createTransaction()
Create a new transaction.JTransaction
createTransaction(boolean allowNewSchema, ValidationMode validationMode)
Create a new transaction.JTransaction
createTransaction(boolean allowNewSchema, ValidationMode validationMode, Map<String,?> kvoptions)
Create a new transaction with key/value transaction options.JTransaction
createTransaction(KVTransaction kvt, boolean allowNewSchema, ValidationMode validationMode)
Create a new transaction using an already-openedKVTransaction
.<T> JClass<? super T>
findJClass(Class<T> type)
Find the most specificJClass
for which the give type is a sub-type of the corresponding Java model type.int
getActualVersion()
Get the schema version that this instance used for the most recently created transaction.int
getConfiguredVersion()
Get the schema version that this instance was configured to use.Database
getDatabase()
Get the core APIDatabase
underlying this instance.JClass<?>
getJClass(int storageId)
Get theJClass
associated with the given storage ID.JClass<?>
getJClass(ObjId id)
Get theJClass
associated with the object ID.<T> JClass<T>
getJClass(Class<T> type)
Get theJClass
modeled by the given type.SortedMap<Integer,JClass<?>>
getJClasses()
Get allJClass
's associated with this instance, indexed by storage ID.<T> List<JClass<? extends T>>
getJClasses(Class<T> type)
Get allJClass
es which sub-type the given type.Map<Class<?>,JClass<?>>
getJClassesByType()
Get allJClass
's associated with this instance, indexed by Java model type.static Class<?>
getModelClass(JObject jobj)
Deprecated.UseJObject.getModelClass()
insteadNameIndex
getNameIndex()
Get aNameIndex
based on this instance's schema model.Iterable<JObject>
getReferencedObjects(JObject jobj)
Utility method to get all of the objects directly referenced by a given object via any field.SchemaModel
getSchemaModel()
Get theSchemaModel
associated with this instance, derived from the annotations on the scanned classes.ReferencePath
parseReferencePath(Class<?> startType, String path)
Parse aReferencePath
containing a target field.ReferencePath
parseReferencePath(Class<?> startType, String path, boolean expectTargetField)
Parse aReferencePath
.void
setConfiguredVersion(int version)
Change the schema version that this instance is configured to use.void
setValidatorFactory(javax.validation.ValidatorFactory validatorFactory)
Configure a customValidatorFactory
used to createValidator
s for validation within transactions.
-
-
-
Field Detail
-
GENERATED_CLASS_NAME_SUFFIX
public static final String GENERATED_CLASS_NAME_SUFFIX
The suffix that is appended to Java model class names to get the corresponding Permazen generated class name.- See Also:
- Constant Field Values
-
-
Constructor Detail
-
Permazen
public Permazen(Iterable<? extends Class<?>> classes)
Create an instance using an initially empty, in-memorySimpleKVDatabase
. Generates a database schema by introspecting theclasses
; auto-generates a schema version number and uses aDefaultStorageIdGenerator
to auto-generate storage ID's.This constructor can also be used just to validate the annotations on the given classes.
- Parameters:
classes
- classes annotated with@PermazenType
annotations- Throws:
IllegalArgumentException
- ifclasses
is nullIllegalArgumentException
- ifclasses
contains a null class or a class with invalid annotation(s)IllegalArgumentException
- ifclasses
contains a class with no suitable subclass constructorInvalidSchemaException
- if the schema implied byclasses
is invalid
-
Permazen
public Permazen(Class<?>... classes)
Create an instance using an initially empty, in-memorySimpleKVDatabase
.Equivalent to
Permazen
(Arrays.asList(classes))
.- Parameters:
classes
- classes annotated with@PermazenType
annotations- See Also:
Permazen(Iterable)
-
Permazen
public Permazen(Database database, int version, StorageIdGenerator storageIdGenerator, Iterable<? extends Class<?>> classes)
Primary constructor.- Parameters:
database
- core database to useversion
- schema version number of the schema derived fromclasses
, zero to use the highest version already recorded in the database, or -1 to use an auto-generated schema versionstorageIdGenerator
- generator for auto-generated storage ID's, or null to disallow auto-generation of storage ID'sclasses
- classes annotated with@PermazenType
annotations; non-annotated classes are ignored- Throws:
IllegalArgumentException
- ifdatabase
orclasses
is nullIllegalArgumentException
- ifversion
is less than -1IllegalArgumentException
- ifclasses
contains a null class or a class with invalid annotation(s)InvalidSchemaException
- if the schema implied byclasses
is invalid
-
-
Method Detail
-
getDatabase
public Database getDatabase()
Get the core APIDatabase
underlying this instance.- Returns:
- underlying
Database
-
getConfiguredVersion
public int getConfiguredVersion()
Get the schema version that this instance was configured to use.This will either be a specific non-zero schema version number, or zero, indicating that the highest schema version found in the database should be used.
If -1 was configured, this will return the actual auto-generated schema version.
- Returns:
- the schema version that this instance will use when opening transactions via
Database.createTransaction()
-
setConfiguredVersion
public void setConfiguredVersion(int version)
Change the schema version that this instance is configured to use.- Parameters:
version
- schema version number of the schema derived fromclasses
, zero to use the highest version already recorded in the database, or -1 to use an auto-generated schema version- Throws:
IllegalArgumentException
- ifversion
is less than -1
-
getActualVersion
public int getActualVersion()
Get the schema version that this instance used for the most recently created transaction.If no transactions have been created yet, this returns zero. Otherwise, it returns the schema version used by the most recently created transaction.
If the
version
passed to the constructor was zero, this method can be used to read the highest schema version seen in the database by the most recently created transaction.If the
version
passed to the constructor was non-zero, and at least one transaction has been created, this method will return the same value.- Returns:
- the schema version that this instance used in the most recently created transaction
-
getModelClass
@Deprecated public static Class<?> getModelClass(JObject jobj)
Deprecated.UseJObject.getModelClass()
insteadGet the Java model class of the givenJObject
.If
jobj
is an instance of a Permazen-generated subclass of a user-supplied Java model class, this returns the original Java model class.- Parameters:
jobj
- database instance- Returns:
- the original Java model class of which
jobj
is an instance - Throws:
IllegalArgumentException
- ifjobj
is null
-
createTransaction
public JTransaction createTransaction()
Create a new transaction.Convenience method; equivalent to:
createTransaction
(true,ValidationMode.AUTOMATIC
, null)- Returns:
- the newly created transaction
- Throws:
InvalidSchemaException
- if the schema does not match what's recorded in the database for the schema version provided to the constructorInvalidSchemaException
- if the schema version provided to the constructor is not recorded in the database andallowNewSchema
is falseInvalidSchemaException
- if the schema version provided to the constructor is not recorded in the database andallowNewSchema
is true, but the schema is incompatible with one or more previous schemas alread recorded in the database (i.e., the same storage ID is used incompatibly between schema versions)InconsistentDatabaseException
- if inconsistent or invalid meta-data is detected in the database
-
createTransaction
public JTransaction createTransaction(boolean allowNewSchema, ValidationMode validationMode)
Create a new transaction.Convenience method; equivalent to:
createTransaction
(allowNewSchema, validationMode, null)- Parameters:
allowNewSchema
- whether creating a new schema version is allowedvalidationMode
- theValidationMode
to use for the new transaction- Returns:
- the newly created transaction
- Throws:
InvalidSchemaException
- if the schema does not match what's recorded in the database for the schema version provided to the constructorInvalidSchemaException
- if the schema version provided to the constructor is not recorded in the database andallowNewSchema
is falseInvalidSchemaException
- if the schema version provided to the constructor is not recorded in the database andallowNewSchema
is true, but the schema is incompatible with one or more previous schemas alread recorded in the database (i.e., the same storage ID is used incompatibly between schema versions)InconsistentDatabaseException
- if inconsistent or invalid meta-data is detected in the databaseIllegalArgumentException
- ifvalidationMode
is null
-
createTransaction
public JTransaction createTransaction(boolean allowNewSchema, ValidationMode validationMode, Map<String,?> kvoptions)
Create a new transaction with key/value transaction options.This does not invoke
JTransaction.setCurrent()
: the caller is responsible for doing that if necessary. However, this method does arrange forJTransaction.setCurrent
(null)
to be invoked as soon as the returned transaction is committed (or rolled back), assumingJTransaction.getCurrent()
returns theJTransaction
returned here at that time.- Parameters:
allowNewSchema
- whether creating a new schema version is allowedvalidationMode
- theValidationMode
to use for the new transactionkvoptions
- optionalKVDatabase
-specific transaction options; may be null- Returns:
- the newly created transaction
- Throws:
InvalidSchemaException
- if the schema does not match what's recorded in the database for the schema version provided to the constructorInvalidSchemaException
- if the schema version provided to the constructor is not recorded in the database andallowNewSchema
is falseInvalidSchemaException
- if the schema version provided to the constructor is not recorded in the database andallowNewSchema
is true, but the schema is incompatible with one or more previous schemas alread recorded in the database (i.e., the same storage ID is used incompatibly between schema versions)InconsistentDatabaseException
- if inconsistent or invalid meta-data is detected in the databaseIllegalArgumentException
- ifvalidationMode
is null
-
createTransaction
public JTransaction createTransaction(KVTransaction kvt, boolean allowNewSchema, ValidationMode validationMode)
Create a new transaction using an already-openedKVTransaction
.This does not invoke
JTransaction.setCurrent()
: the caller is responsible for doing that if necessary. However, this method does arrange forJTransaction.setCurrent
(null)
to be invoked as soon as the returned transaction is committed (or rolled back), assumingJTransaction.getCurrent()
returns theJTransaction
returned here at that time.- Parameters:
kvt
- already opened key/value store transactionallowNewSchema
- whether creating a new schema version is allowedvalidationMode
- theValidationMode
to use for the new transaction- Returns:
- the newly created transaction
- Throws:
InvalidSchemaException
- if the schema does not match what's recorded in the database for the schema version provided to the constructorInvalidSchemaException
- if the schema version provided to the constructor is not recorded in the database andallowNewSchema
is falseInvalidSchemaException
- if the schema version provided to the constructor is not recorded in the database andallowNewSchema
is true, but the schema is incompatible with one or more previous schemas alread recorded in the database (i.e., the same storage ID is used incompatibly between schema versions)InconsistentDatabaseException
- if inconsistent or invalid meta-data is detected in the databaseIllegalArgumentException
- ifkvt
orvalidationMode
is null
-
createSnapshotTransaction
public SnapshotJTransaction createSnapshotTransaction(ValidationMode validationMode)
Create a new, emptySnapshotJTransaction
backed by aNavigableMapKVStore
.The returned
SnapshotJTransaction
does not supportcommit()
orrollback()
, and can be used indefinitely.- Parameters:
validationMode
- theValidationMode
to use for the snapshot transaction- Returns:
- initially empty snapshot transaction
-
createSnapshotTransaction
public SnapshotJTransaction createSnapshotTransaction(KVStore kvstore, boolean allowNewSchema, ValidationMode validationMode)
Create a newSnapshotJTransaction
based on the provided key/value store.The key/value store will be initialized if necessary (i.e.,
kvstore
may be empty), otherwise it will be validated against the schema information associated with this instance.The returned
SnapshotJTransaction
does not supportcommit()
orrollback()
, and can be used indefinitely.If
kvstore
is aCloseableKVStore
, then it will beclose()
'd if/when the returnedSnapshotJTransaction
is.- Parameters:
kvstore
- key/value store, empty or having content compatible with this transaction'sPermazen
allowNewSchema
- whether creating a new schema version inkvstore
is allowedvalidationMode
- theValidationMode
to use for the snapshot transaction- Returns:
- snapshot transaction based on
kvstore
- Throws:
SchemaMismatchException
- ifkvstore
contains incompatible or missing schema informationInconsistentDatabaseException
- if inconsistent or invalid meta-data is detected in the databaseIllegalArgumentException
- ifkvstore
is null
-
getSchemaModel
public SchemaModel getSchemaModel()
Get theSchemaModel
associated with this instance, derived from the annotations on the scanned classes.- Returns:
- the associated schema model
-
getNameIndex
public NameIndex getNameIndex()
Get aNameIndex
based on this instance's schema model.- Returns:
- a name index on this instance's schema model
-
getJClasses
public SortedMap<Integer,JClass<?>> getJClasses()
Get allJClass
's associated with this instance, indexed by storage ID.- Returns:
- read-only mapping from storage ID to
JClass
-
getJClassesByType
public Map<Class<?>,JClass<?>> getJClassesByType()
Get allJClass
's associated with this instance, indexed by Java model type.- Returns:
- read-only mapping from Java model type to
JClass
-
getJClass
public <T> JClass<T> getJClass(Class<T> type)
Get theJClass
modeled by the given type.- Type Parameters:
T
- Java model type- Parameters:
type
- an annotated Java object model type- Returns:
- associated
JClass
- Throws:
IllegalArgumentException
- iftype
is not equal to a known Java object model type
-
findJClass
public <T> JClass<? super T> findJClass(Class<T> type)
Find the most specificJClass
for which the give type is a sub-type of the corresponding Java model type.- Type Parameters:
T
- Java model type or subtype thereof- Parameters:
type
- (sub)type of some Java object model type- Returns:
- narrowest
JClass
whose Java object model type is a supertype oftype
, or null if none found
-
getJClass
public JClass<?> getJClass(ObjId id)
Get theJClass
associated with the object ID.- Parameters:
id
- object ID- Returns:
JClass
instance- Throws:
TypeNotInSchemaVersionException
- ifid
has a type that does not exist in this instance's schema versionIllegalArgumentException
- ifid
is null
-
getJClass
public JClass<?> getJClass(int storageId)
Get theJClass
associated with the given storage ID.- Parameters:
storageId
- object type storage ID- Returns:
JClass
instance- Throws:
UnknownTypeException
- ifstorageId
does not represent an object type
-
getJClasses
public <T> List<JClass<? extends T>> getJClasses(Class<T> type)
Get allJClass
es which sub-type the given type.- Type Parameters:
T
- Java model type- Parameters:
type
- type restriction, or null for no restrction- Returns:
- list of
JClass
es whose type istype
or a sub-type, ordered by storage ID
-
parseReferencePath
public ReferencePath parseReferencePath(Class<?> startType, String path)
Parse aReferencePath
containing a target field.Equivalent to:
parseReferencePath
(startType, path, true)
.- Parameters:
startType
- starting Java type for the pathpath
- dot-separated path of zero or more reference fields, followed by a target field- Returns:
- parsed reference path
- Throws:
IllegalArgumentException
- ifpath
is invalidIllegalArgumentException
- ifstartType
orpath
is null- See Also:
ReferencePath
-
parseReferencePath
public ReferencePath parseReferencePath(Class<?> startType, String path, boolean expectTargetField)
Parse aReferencePath
.- Parameters:
startType
- starting Java type for the pathpath
- dot-separated path of zero or more reference fields, followed by an optional target fieldexpectTargetField
- true ifpath
contains a target field, false otherwise- Returns:
- parsed reference path
- Throws:
IllegalArgumentException
- ifpath
is invalidIllegalArgumentException
- ifstartType
orpath
is null- See Also:
ReferencePath
-
setValidatorFactory
public void setValidatorFactory(javax.validation.ValidatorFactory validatorFactory)
Configure a customValidatorFactory
used to createValidator
s for validation within transactions.- Parameters:
validatorFactory
- factory for validators- Throws:
IllegalArgumentException
- ifvalidatorFactory
is null
-
getReferencedObjects
public Iterable<JObject> getReferencedObjects(JObject jobj)
Utility method to get all of the objects directly referenced by a given object via any field.Note: the returned
Iterable
may contain duplicates; these can be eliminated using anObjIdSet
if necessary.- Parameters:
jobj
- starting object- Returns:
- all objects directly referenced by
jobj
- Throws:
IllegalArgumentException
- ifjobj
is null
-
-