Class SRecordInstance
- All Implemented Interfaces:
Serializable
- Direct Known Subclasses:
PersistentRecord
RecordInstances are normally created by either findOrCreate
or
SSessionJdbc#Query
. The former selects a specific record by primary key, while the latter retrieves all
records that satify a query. Instances may also be directly created by without
reference to a session.
The main methods are get*
and set*
which get and set field values of the record.
deleteRecord()
deletes a row.
No two RecordInstances can have the same primary key field values within the same connection. Attempts to retrieve the same row twice will simple return a pointer to an existing SRecordInstance. There is no relationship between RecordInstances in different connections -- all locking is done by the underlying database.
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic class
Exception thrown due to broken optimistic locks. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionFor debugging like toString(), but shows all the fields.void
Throws an excpetion if !isNewRow()
.void
void
defineInitialValue
(SFieldMeta field) Defines the current value of the field to be the initial value, which is then used for optimistic locks etc.void
Sets a flag to delete this record when the transaction is commited.void
void
boolean
Determines whehter two SRecordInstances are for the same SRecordMeta and have the same primary key fields.<T extends SRecordInstance>
TfindReference
(SFieldReference<T> field) <T extends SRecordInstance>
TfindReference
(SFieldReference<T> field, SQueryMode queryMode) <T extends SRecordInstance>
TfindReference
(SFieldReference<T> field, SQueryMode queryMode, SSelectMode selectMode) Gets a record referenced bythis.field
.<T extends SRecordInstance>
TfindReference
(SFieldReference<T> field, SSelectMode selectMode) getBigDecimal
(SFieldMeta field) etc.boolean
getBoolean
(SFieldMeta field) Returns false if null.byte[]
getBytes
(SFieldMeta field) Casts getObject() to byte[].getDate
(SFieldMeta field) etc.double
getDouble
(SFieldMeta field) Casts getObject() to double iff a Number, see getString().<T extends Enum<T>>
TgetEnum
(SFieldEnum<T> field) getInitialValue
(SFieldMeta fieldMeta) The value that was read from (or flushed to) the database.int
getInt
(SFieldMeta field) Casts getObject() to int iff a Number, see getString().long
getLong
(SFieldMeta field) Casts getObject() to long iff a Number, see getString().abstract SRecordMeta<?>
getMeta()
This must be defined in every user record's definition to access the SRecord which provides the meta data for this instance.getObject
(SFieldMeta field) Returns the field's value as a Java Object in the type stored in the dataset.getRawArrayValue
(SFieldMeta fmeta) Raw accessor for field value.Get a reference, but do not query either the dataset or the database.getString
(SFieldMeta field) Gets the value of field cast to a String, trimed of trailing spaces.getTime
(SFieldMeta field) etc.getTimestamp
(SFieldMeta field) etc.int
hashCode()
Seeequals()
.boolean
True if this instance is attached to the current begun transaction.boolean
boolean
isDirty()
True iff this record is dirty but not yet flushed to the database.boolean
isDirty
(SFieldMeta field) Tests whether just field is dirty.boolean
isEmpty
(SFieldMeta field) True if field is the empty value, ie.boolean
isNewRow()
Often called after {SRecordMeta#findOrCreate} to determine whether a row was retrieved from the database (not a new row) or whether this record represents a new row that will be inserted when it is flushed.boolean
True if the record has valid data, ie.boolean
isNull
(SFieldMeta field) Was the field SQL NULL in the database? (eg.boolean
boolean
isValid
(SFieldMeta field) True if the field has been queried as part of the current transaction and so a get is valid.protected void
Override this to get field values just after a record is actually retrieved, by findOrCreate or query.protected void
onValidateField
(SFieldMeta field, Object newValue) Called after individual field validators each time a field's value is set, (now) including keys.protected void
Override this to validate records before flush.void
setBigDecimal
(SFieldMeta field, BigDecimal value) void
setBoolean
(SFieldMeta field, boolean value) void
setBytes
(SFieldMeta field, byte[] value) void
setDate
(SFieldMeta field, Date value) SeesetTimestamp(simpleorm.dataset.SFieldMeta, java.util.Date)
for discussion of Date parameter.void
setDirty
(boolean val) Sets this record to be dirty so that it will be updated in the database.void
setDouble
(SFieldMeta field, double value) void
setEmpty
(SFieldMeta field) Sets field to be empty, ie.<T extends Enum<T>>
voidsetEnum
(SFieldEnum<T> field, Enum<T> value) void
setInt
(SFieldMeta field, int value) void
setLong
(SFieldMeta field, long value) void
setNewRow
(boolean val) void
setNull
(SFieldMeta field) void
setObject
(SFieldMeta field, Object value) Generic routine to set a fields value.void
setObject
(SFieldMeta field, Object value, boolean fieldValidate) Enables value to be set with field validation suppressed, rarely used.void
setRawArrayValue
(SFieldMeta fmeta, Object value) Raw setter for field value.void
setReadOnly
(boolean val) void
setReference
(SFieldReference<?> field, SRecordInstance value) void
setString
(SFieldMeta field, String value) Sets the value of the field from a string, casting if necessary.void
setTime
(SFieldMeta field, Date value) SeesetTimestamp(simpleorm.dataset.SFieldMeta, java.util.Date)
for discussion of Date parameter.void
setTimestamp
(SFieldMeta field, Date value) Note that value should normally be a java.sql.Timestamp (a subclass of java.util.Date).toString()
toString just shows the Key field(s).void
boolean
Was in the cache before the most recent findOrCreate.
-
Constructor Details
-
SRecordInstance
protected SRecordInstance()Protected default constructor. Necessary to allow definition of record with no explicit constructor. If overriding is REALLY necessary, don't forget to call super();
-
-
Method Details
-
getMeta
This must be defined in every user record's definition to access the SRecord which provides the meta data for this instance. It is normally defined as:-SRecord getMeta() { return meta; };
The actual
meta
variable is thus not Serialized, but it would not be anyway as it is usually static. -
equals
Determines whehter two SRecordInstances are for the same SRecordMeta and have the same primary key fields.This is purely for the purpose of putting
SRecordInstances
in theSSession.transactionCache
. This is done astc.put(SRecordInstance, SRecordInstance)
, ie the instance is used for both the key and the body. This avoids having to create a separate primary key object for each record instance.It only foreign keys, not referenced SRecordInstances which may be null if the parent record has not been retrieved.
-
hashCode
public int hashCode()Seeequals()
. -
getObject
Returns the field's value as a Java Object in the type stored in the dataset.Methods such as
getString()
dispach to this method but are generally more convenient because the cast the result to the correct type. This method in turn just dispaches tofield.getFieldValue()
, ie. it is the declaredtype of the SField that determines how the value is retrieved.Also lazily fetches referenced records if field is a reference. But findReference normally used instead. Don't rely on null result, as it could mean field is null, or it has not been queried or set. Use isNull(field) instead.
Enums are now stored as enums.
-
setObject
Generic routine to set a fields value. Just dispaches tofield.setFieldValue(convertToField(value))
-
setObject
Enables value to be set with field validation suppressed, rarely used. -
isNull
Was the field SQL NULL in the database? (eg. getInt would return 0 for this case.) Does not need to do query for reference fields, just checks if any refing scalars are null. -
setNull
-
isEmpty
True if field is the empty value, ie. null or "" or spaces.- See Also:
-
setEmpty
Sets field to be empty, ie. currentlysetObject(, null)
. But other options will be added later.- See Also:
-
getString
Gets the value of field cast to a String, trimed of trailing spaces. This is equivalent togetObject().toString().trimTrailingSpaces()
. So the field type itself need not beSFieldString
, but just something that can be cast to a String. Trailing spaces can be a problem with some databases and fileds declaredCHAR
.Note that if you do not want trailing spaces trimmed, then just call getObject().toString() manually. (For CHAR fields, most dbs/jdbc drivers seem to trim, but this is highly inconsistent.)
## Trimming is an issue with CHAR style fields that pad with spaces. Currently we always read from database into the fields without trimming. The idea being to let the SimpleORM user get at the raw query result using getObject, whatever that raw result is.
Most DBs seem to trim for us. But some may not, and some may require the trailing spaces on queries. Certainly trailing spaces in the objects will upset the record cache, and there is some dubious code in SRecordFinder.retrieveRecord() to handle this.
I think that for CHAR fields we need to always trim at database read, and pad where needed. This should also be dispatched to DB handler. I think that Oracle gives grief. (Note that trim means trailing spaces, leading should be left alone.)
I have not done this because it would require testing on many datbases.
-
setString
Sets the value of the field from a string, casting if necessary. So this can be used to set an Integer field, say. -
getInt
Casts getObject() to int iff a Number, see getString(). Returns 0 if null, following JDBC. -
setInt
-
getLong
Casts getObject() to long iff a Number, see getString(). Returns 0 if null, following JDBC. Note that longs may not be accurately supported by the database -- see SFieldLong. -
setLong
-
getDouble
Casts getObject() to double iff a Number, see getString(). Returns 0 if null, following JDBC. -
setDouble
-
getBoolean
Returns false if null. -
setBoolean
-
getTimestamp
etc. for Timestamp. -
setTimestamp
Note that value should normally be a java.sql.Timestamp (a subclass of java.util.Date). However, if it is a java.util.Date instead, then it will replaced by a new java.sql.Timestamp object before being set. This is convenient for people using java.util.Date as their main date type. -
getDate
etc. for Date. ### Should convert strings to Date, ISO etc. Likewise other types. (Painful to do in Java!) -
setDate
SeesetTimestamp(simpleorm.dataset.SFieldMeta, java.util.Date)
for discussion of Date parameter. -
getTime
etc. for Time. -
setTime
SeesetTimestamp(simpleorm.dataset.SFieldMeta, java.util.Date)
for discussion of Date parameter. -
getBigDecimal
etc. for BigDecimal. -
setBigDecimal
-
getEnum
-
setEnum
-
getBytes
Casts getObject() to byte[]. -
setBytes
-
findReference
public <T extends SRecordInstance> T findReference(SFieldReference<T> field, SQueryMode queryMode, SSelectMode selectMode) Gets a record referenced bythis.field
. Does a lazy lookup on the SDataSet.getSession() if necessary, and if attached to a session.If the field is null but all the primary key fields are non null then does a
dataset.find()
and if necessary aSSessionI.findOrCreate()
to provide a referenced record. -
findReference
public <T extends SRecordInstance> T findReference(SFieldReference<T> field, SSelectMode selectMode) -
findReference
-
findReference
-
setReference
-
getReferenceNoQuery
Get a reference, but do not query either the dataset or the database. Returns null if a corresponding scalar field is null. Returns Boolean.FALSE if it is not null, but has not been queried from the database. -
setDirty
public void setDirty(boolean val) Sets this record to be dirty so that it will be updated in the database. Normally done implicitly by setting a specific column.NOP - But may occasionally be useful after a findOrInsert() to add a record that contains nothing appart from its primary key. ===> isNewRow is here for that
-
isDirty
public boolean isDirty()True iff this record is dirty but not yet flushed to the database. May be both dirty and unattached.A record is not dirty if a record has been flushed to the database but the transaction not committed.
## Should add wasEverDirty method for both record and fields for validation tests.
-
isDirty
Tests whether just field is dirty. -
wasInCache
public boolean wasInCache()Was in the cache before the most recent findOrCreate. (Will always been in the cache after a findOrCreate.) Used to prevent two create()s for the same key. Also for unit tests. -
deleteRecord
public void deleteRecord()Sets a flag to delete this record when the transaction is commited. The record is not removed from the transaction cache. Any futurefindOrCreate
will thus return the deleted record but its fields may not be referenced. (isDeleted
can be used to determine that the record has been deleted.)The record is only deleted from the database when the transaction is committed or is flushed. Thus a transaction that nulls out references to a parent record and then deletes the parent record will not cause a referential integrity violation because the update order is preserved so that the updates will (normally) be performed before the deletes.
Note that for Optimistic locks only those fields that were retrieved are checked for locks.
-
isDeleted
public boolean isDeleted() -
isNewRow
public boolean isNewRow()Often called after {SRecordMeta#findOrCreate} to determine whether a row was retrieved from the database (not a new row) or whether this record represents a new row that will be inserted when it is flushed. -
setNewRow
public void setNewRow(boolean val) -
assertNewRow
public void assertNewRow()Throws an excpetion if !isNewRow()
. Handy, use often in your code to trap nasty errors. -
assertNotNewRow
public void assertNotNewRow()- See Also:
-
isNotDestroyed
public boolean isNotDestroyed()True if the record has valid data, ie. it has not been destroyed. (This has nothing to do with validateRecord.) -
isValid
True if the field has been queried as part of the current transaction and so a get is valid. Use this to guard validations if partial column queries are performed. See isDirty. -
isAttached
public boolean isAttached()True if this instance is attached to the current begun transaction. Exception if is attached but not to the current transaction or the current transaction has not begun. #### not right. -
toString
toString just shows the Key field(s). It is meant to be consise, often used as part of longer messages. -
allFields
For debugging like toString(), but shows all the fields. -
onValidateField
Called after individual field validators each time a field's value is set, (now) including keys. Not called as values are retrieved from database.Throw an SException.Validation if not OK. The value is not assigned, and the transaction can continue. The exception will be augmented with
This is called after the value has been converted to its proper type, eg. from a String to a Double and the field value has been updated.
If the validation fails, the field is automatically set back to its oldValue.
This is called for key values as well. This is only for newly created records but is during the findOrCreate -- ie it is called even if the record is never made dirty and thus saved.
-
doValidateRecord
public void doValidateRecord() -
onValidateRecord
protected void onValidateRecord()Override this to validate records before flush. Throw an SValidationException if not OK.This is called just before a record would be flushed. Only dirty records are validated. If the validation fails then the record is not flushed. (It may also be called directly by the application to validate the record before it is flushed.)
Use this routine when a record may be in a temporarily invalid state, but which must be corrected before flushing. This is common when there is a more complex relationship between different fields that cannot be validated until all the fields have been assigned values.
-
onQueryRecord
protected void onQueryRecord()Override this to get field values just after a record is actually retrieved, by findOrCreate or query. -
doQueryRecord
public void doQueryRecord() -
validatePrimaryKeys
public void validatePrimaryKeys() -
setRawArrayValue
Raw setter for field value. Internal to Simpleorm. Assigns directly into the array of values. No validation or conversion.- Parameters:
fmeta
- the field to setvalue
- the new value of the field, as is, can be null
-
getRawArrayValue
Raw accessor for field value. Internal to Simpleorm. Gets directly from the array of values. No findReference. No Valid test.- Parameters:
fmeta
- the field to get
-
getInitialValue
The value that was read from (or flushed to) the database. Used for optimistic locking, and also just to tell how fields change. -
defineInitialValue
Defines the current value of the field to be the initial value, which is then used for optimistic locks etc. Called just after a record is read or updated. -
getLogger
-
isReadOnly
public boolean isReadOnly() -
setReadOnly
public void setReadOnly(boolean val) -
getDataSet
-