Package com.isomorphic.jpa

# Class JPADataSource

java.lang.Object
com.isomorphic.base.Base
com.isomorphic.datasource.DataSource
com.isomorphic.datasource.BasicDataSource
com.isomorphic.jpa.JPADataSource

All Implemented Interfaces:
  `com.isomorphic.base.IAutoConfigurable`, `com.isomorphic.datasource.Committable`, `com.isomorphic.datasource.FreeResourcesHandler`, `com.isomorphic.datasource.IType`, `IToJSON`, `Serializable`

Direct Known Subclasses:
  `GAEJPADataSource`, `JPA2DataSource`

public class JPADataSource extends BasicDataSource
Server side implementation of JPA 1.0 data source.

This class supports search with advanced criteria.

This class supports fields with `valueXPath` setting. Entity property is accessed (by priority):

1. `valueXPath` - supports only simple XPath definitions: "property/subProperty/subSubProperty"
2. `name` - most often used when data source field name is the same as entity property name

Transaction management:

- Operating under RPCManager (`DSRequest` has reference to `RPCManager`):
  - If participates in automatic transactions:
    - retrieves existing transaction from `RPCManager` (if exists);
    - starts new transaction (if not found in `RPCManager`);
  - If one transaction per operation is used - starts new transaction;
  - Registers itslef to `DSRequest.registerCallback()` for `onSuccess()`/ `onFailure()` execution to commit/roll back transaction;
  - Sets `DSRequest.setFreeOnExecute()` to `false` to postpone releasing of `EntityManager` avoiding lazy loading exceptions when creating JS response and traversing through persistent object tree;
  - Registers itslef to `RPCManager.registerFreeResourcesHandler()` for `freeResources()` execution to release `EntityManager`.
- Operating without RPCManager:
  - starts new transaction;
  - commits/rolls back transaction and releases `EntityManager` if `DSRequest.setFreeOnExecute()` is set to `true` (default);
  - relies on calling code to call `onSuccess()`/`onFailure()` to commit/roll back transaction and to call `freeResources()` to release `EntityManager`.
    Example code for data source operation execution with manual transaction handling:

                      DSRequest req = new DSRequest("myDS", "fetch");
                      req.setFreeOnExecute(false);
                      DSResponse resp = req.execute();
                      List dataList = resp.getDataList();
                      //... traverse through persistent object tree
                      // Commit current transaction.
                      ((JPADataSource) r.getDataSource()).onSuccess();
                      // Release entity manager.
                      ((JPADataSource) r.getDataSource()).freeResources(req);

Implementation is not thread-safe. Data source acquiring mechanism ensures that single instance of this class will be used in one thread only.

See Also:
  - Serialized Form

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `protected Map<String,DSField>`
  `additionalFields`
  Holds list of additional fields requested by specific `DSRequest`.
  `static final String`
  `AUTO_DERIVE_PROPERTY`
  Name of the data source definition property holding should data source be auto derived.
  `static final String`
  `BEAN_CLASS_PROPERTY`
  Name of the data source definition property holding fully-qualified class name.
  `protected Class`
  `beanClass`
  Holds class from the DataSource definition.
  `protected String`
  `beanName`
  Holds bean name - simple class name with preceding underscore.
  `protected String`
  `configName`
  Holds config name - can be configured with "jpaConfig" parameter.
  `protected JPAConnectionHolder`
  `connectionHolder`
  Holds connection information for Automatic Transactions.
  `protected jakarta.persistence.EntityManager`
  `em`
  Holds entity manager for operations with underlying data.
  `static final Character`
  `ESCAPE_CHARACTER`
  Holds character ('~') used to escape wild cards in 'like' clause.
  `protected Boolean`
  `generateRelatedUpdates`
  Holds value should related updates be generated.
  `static final String`
  `ID_CLASS_PROPERTY`
  Name of the data source definition property holding fully-qualified class name for composite primary key.
  `protected Class`
  `idClass`
  Holds id class from the DataSource definition.
  `static final String`
  `JPA_CONFIG_PROPERTY`
  Name of the JPA configuration name property.
  `protected List<DSResponse>`
  `relatedUpdates`
  Holds list of generated related updates.
  `static final String`
  `SCHEMA_BEAN_PROPERTY`
  Name of the data source definition property holding should data source be auto derived from specified mapped entity.
  `protected boolean`
  `shouldRollBackTransaction`
  Flag used to indicate that transaction should be rolled back.
  `protected boolean`
  `strictSQLFiltering`
  If set to true, advanced filtering will follow SQL99 behavior for dealing with NULL values, which is often counter-intuitive to users.
  `protected Object`
  `tx`
  Holds transaction object.
  `static final String`
  `USE_QUALIFIED_CLASS_NAME_PROPERTY`
  Name of property specifying should fully-qualified class name be used in query string.
  `protected Boolean`
  `useQualifiedClassName`
  According to JPA specifications only simple class name can be used in queries.

  ### Fields inherited from class com.isomorphic.datasource.DataSource

  `OP_ADD, OP_CLIENT_EXPORT, OP_CUSTOM, OP_DOWNLOAD_FILE, OP_FETCH, OP_GET_FILE, OP_GET_FILE_VERSION, OP_HAS_FILE, OP_HAS_FILE_VERSION, OP_LIST_FILE_VERSIONS, OP_LIST_FILES, OP_LOAD_SCHEMA, OP_REMOVE, OP_REMOVE_FILE, OP_REMOVE_FILE_VERSION, OP_RENAME_FILE, OP_SAVE_FILE, OP_UNIQUE_NAME, OP_UPDATE, OP_VALIDATE, OP_VIEW_FILE`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `Map<String,Object>`
  `deriveDS(String schemaBean, String id, boolean extended)`
  Creates data source configuration from specified fully qualified class name.
  `static String`
  `escapeValueForFilter(Object value, char escapeChar)`
  Escapes characters "_" and "%" with specified character in value object.
  `DSResponse`
  `execute(DSRequest req)`
  This method carries out the actual processing of a DataSource request.
  `DSResponse`
  `executeAdd(DSRequest req)`
  This method is called by DataSource.execute() for "add" operations.
  `DSResponse`
  `executeFetch(DSRequest req)`
  This method is called by DataSource.execute() for "fetch" operations.
  `DSResponse`
  `executeRemove(DSRequest dsRequest)`
  This method is called by DataSource.execute() for "remove" operations.
  `DSResponse`
  `executeUpdate(DSRequest req)`
  This method is called by DataSource.execute() for "update" operations.
  `void`
  `freeResources(DSRequest req)`
  Closes `EntityManager`.
  `DSField`
  `getField(String fieldName)`
  Returns `DSField` by specified name.
  `List`
  `getFieldNames(boolean dropIgnored)`
  Returns combined list of data source configured and request configured field names.
  `String`
  `getTransactionObjectKey(boolean longForm)`
  `void`
  `increaseOpCount()`
  Increases operations count by 1.
  `void`
  `init(Map theConfig, DSRequest dsRequest)`
  `void`
  `markTransactionForRollBack(DSResponse dsResponse)`
  Sets flag that current transaction should be rolled back.

  ### Methods inherited from class com.isomorphic.datasource.BasicDataSource

  `getAuditDataSource, getAuditRecord, getAuditRecord, getFTSEligibleFields, getFTSProviderForField, getFullTextSearchConfig, hasCustomDefaultFetchOperation, hasCustomLogic, isFieldFTSEligible, isFullTextSearchEnabled, shouldAutoJoinTransaction, shouldAutoStartTransaction, transformMultipleFields, transformMultipleFields, writeMultiAudits`

  ### Methods inherited from class com.isomorphic.datasource.DataSource

  `add, add, addDynamicDSGenerator, addDynamicDSGenerator, addDynamicDSGenerator, clearDynamicDSGenerators, convertRelativeDates, convertRelativeDates, convertRelativeDates, convertRelativeDates, convertRelativeDates, convertRelativeDates, executeFileSource, fetch, fetch, fetchById, fetchById, fetchById, fetchSingle, fetchSingle, filter, filter, fromXML, fromXML, fromXML, fromXML, fromXML, fromXML, fromXML, fromXML, get1ManyRelationFields, getAuditChangedFieldsFieldName, getAuditRevisionFieldName, getAuditTimestampFieldName, getAuditTypeFieldName, getAuditUserFieldName, getDefaultDynamicDSGenerator, getDirectFields, getDynamicDSGenerators, getEnumConstantProperty, getEnumOrdinalProperty, getEnumTranslateStrategy, getFieldNames, getFile, getFileAsInputStream, getFileAsString, getFileContentsField, getFileFormatField, getFileNameField, getFileTypeField, getID, getJoinDSName, getJoinDSName, getListProperties, getListProperties, getListProperty, getManyManyRelationFields, getMapProperty, getName, getNonIncludedFields, getObjectProperty, getOperationProperty, getPrimaryKey, getProperties, getProperties, getProperties, getProperty, getPropertyJavaClass, getRecordXPath, getRelatedDisplayRecord, getRelatedDisplayRecord, getRelatedDSName, getRelatedDSName, getRelatedTableAlias, getRelationFields, getTableName, getTransactionObject, getTransactionObject, has1ManyRelationFields, hasFile, hasManyManyRelationFields, hasRecord, hasRecord, hasRelationFields, initialized, is1ManyRelationField, isManyManyRelationField, isModificationOperation, isRelationField, isServerOnly, listFiles, listFiles, listFiles, listFiles, listFiles, listFiles, remove, removeDynamicDSGenerator, removeDynamicDSGenerator, removeDynamicDSGenerator, removeFile, renameFile, saveFile, setEnumConstantProperty, setEnumOrdinalProperty, setEnumTranslateStrategy, setOmitNullMapValuesInResponse, setProperties, transformImportValue, transformImportValue, transformResponse, update, update, validate, validate, validate, validateRecord`

- ## Field Details

  - ### BEAN_CLASS_PROPERTY

    public static final String BEAN_CLASS_PROPERTY
    Name of the data source definition property holding fully-qualified class name.
    See Also:
      - Constant Field Values

  - ### AUTO_DERIVE_PROPERTY

    public static final String AUTO_DERIVE_PROPERTY
    Name of the data source definition property holding should data source be auto derived.
    See Also:
      - Constant Field Values

  - ### SCHEMA_BEAN_PROPERTY

    public static final String SCHEMA_BEAN_PROPERTY
    Name of the data source definition property holding should data source be auto derived from specified mapped entity.
    See Also:
      - Constant Field Values

  - ### ID_CLASS_PROPERTY

    public static final String ID_CLASS_PROPERTY
    Name of the data source definition property holding fully-qualified class name for composite primary key.
    See Also:
      - Constant Field Values

  - ### ESCAPE_CHARACTER

    public static final Character ESCAPE_CHARACTER
    Holds character ('~') used to escape wild cards in 'like' clause. Avoid using backslash '\' or dollar sign '$' because it is often used in databases as DB escape or wild card characters.

  - ### JPA_CONFIG_PROPERTY

    public static final String JPA_CONFIG_PROPERTY
    Name of the JPA configuration name property.
    See Also:
      - Constant Field Values

  - ### configName

    protected String configName
    Holds config name - can be configured with "jpaConfig" parameter. Holds empty string for default configuration.

  - ### beanClass

    protected Class beanClass
    Holds class from the DataSource definition.

  - ### beanName

    protected String beanName
    Holds bean name - simple class name with preceding underscore. Defaults to "_beanName" if class is anonymous. Used in creating query.

  - ### idClass

    protected Class idClass
    Holds id class from the DataSource definition.

  - ### strictSQLFiltering

    protected boolean strictSQLFiltering
    If set to true, advanced filtering will follow SQL99 behavior for dealing with NULL values, which is often counter-intuitive to users.

  - ### USE_QUALIFIED_CLASS_NAME_PROPERTY

    public static final String USE_QUALIFIED_CLASS_NAME_PROPERTY
    Name of property specifying should fully-qualified class name be used in query string.
    See Also:
      - Constant Field Values

  - ### useQualifiedClassName

    protected Boolean useQualifiedClassName
    According to JPA specifications only simple class name can be used in queries. Some providers follows these specs strictly (for example EclipseLink). Some providers allows using fully-qualified class name usage (for example Hibernate, Datanucleus). Setting defaults to `false` - simple class name usage. To resolve class name collisions this setting can be set to `true` (should be used with provider supporting fully-qualified class name usage).

  - ### em

    protected jakarta.persistence.EntityManager em
    Holds entity manager for operations with underlying data.

  - ### tx

    protected Object tx
    Holds transaction object.

  - ### shouldRollBackTransaction

    protected boolean shouldRollBackTransaction
    Flag used to indicate that transaction should be rolled back.

  - ### connectionHolder

    protected JPAConnectionHolder connectionHolder
    Holds connection information for Automatic Transactions.

  - ### additionalFields

    protected Map<String,DSField> additionalFields
    Holds list of additional fields requested by specific `DSRequest`.

  - ### relatedUpdates

    protected List<DSResponse> relatedUpdates
    Holds list of generated related updates. Usage: set this field to empty list before executing `setProperties()`; subsequent calls to `setRelationFieldValue()` will add `DSResponse` objects for every change in related data sources.

  - ### generateRelatedUpdates

    protected Boolean generateRelatedUpdates
    Holds value should related updates be generated. (Re)initialized on every `execute()` call. `true` - related updates will be generated; `false` - related updates will not be generated; `null` - related updates will be generated only for "add" and "update" operations, related updates will not be generated for "remove" operation.

- ## Method Details

  - ### init

    public void init(Map theConfig, DSRequest dsRequest) throws Exception
    Throws:
      `Exception`

  - ### deriveDS

    public Map<String,Object> deriveDS(String schemaBean, String id, boolean extended)
    Creates data source configuration from specified fully qualified class name.
    Parameters:
      `schemaBean` - `String` Fully qualified class name.
      `id` - `String` Id for newly created data source.
      `extended` - `boolean` Extended properties will be captured if set to `true`.
    Returns:
      `Map<String, Object>` created data source configuration or `null` if it can not be created.

  - ### getFieldNames

    public List getFieldNames(boolean dropIgnored)
    Returns combined list of data source configured and request configured field names.
    Parameters:
      `dropIgnored` - `boolean` `true` - ignored fields are dropped; `false` - ignored fields are included;
    Returns:
      `List` field names.

  - ### getField

    public DSField getField(String fieldName)
    Returns `DSField` by specified name. First checks data source configured fields. Checks request configured fields if it is not found within data source configured fields. Returns `null` if `fieldName` parameter is `null` or field is not found.
    Overrides:
      `getField` in class `BasicDataSource`
    Parameters:
      `fieldName` - the name of the field whose definition you want
    Returns:
      `DSField` field.
    See Also:
      - `DSField`

  - ### execute

    public DSResponse execute(DSRequest req) throws Exception
    This method carries out the actual processing of a DataSource request. It can be overridden to provide centralized logic that applies to all operation types (such as transaction management, for example), or to implement special validation rules that cannot be handled by the built-in validation system. Generally, however, it is more appropriate to override the method specific to the operationType - executeFetch(), executeRemove(), executeAdd(), executeUpdate() or executeCustom(). Note that you must call the validate() method to retain correct validation behavior if you override this method and do not invoke super() This method is also the place where the transform happens if dataSourceField.multipleStorage is used. The transform is performed by two methods, `DataSource.transformMultipleFields(DSRequest)` and `DataSource.transformMultipleFields(DSResponse)`.
    Overrides:
      `execute` in class `DataSource`
    Parameters:
      `req` - The DSRequest object representing this operation
    Returns:
      A valid DSResponse
    Throws:
      `Exception` - if an error occurs during request execution

  - ### executeFetch

    public DSResponse executeFetch(DSRequest req) throws Exception
    This method is called by DataSource.execute() for "fetch" operations. It is the appropriate override point if you wish to provide custom handling of a "fetch".
    Overrides:
      `executeFetch` in class `DataSource`
    Parameters:
      `req` - The DSRequest object representing this operation
    Returns:
      A valid DSResponse
    Throws:
      `Exception` - if an error occurs during the fetch operation

  - ### executeAdd

    public DSResponse executeAdd(DSRequest req) throws Exception
    This method is called by DataSource.execute() for "add" operations. It is the appropriate override point if you wish to provide custom handling of an "add".
    Overrides:
      `executeAdd` in class `DataSource`
    Parameters:
      `req` - The DSRequest object representing this operation
    Returns:
      A valid DSResponse
    Throws:
      `Exception` - if an error occurs during the add operation

  - ### executeRemove

    public DSResponse executeRemove(DSRequest dsRequest) throws Exception
    This method is called by DataSource.execute() for "remove" operations. It is the appropriate override point if you wish to provide custom handling of a "remove".
    Overrides:
      `executeRemove` in class `DataSource`
    Parameters:
      `dsRequest` - The DSRequest object representing this operation
    Returns:
      A valid DSResponse
    Throws:
      `Exception` - if an error occurs during the remove operation

  - ### executeUpdate

    public DSResponse executeUpdate(DSRequest req) throws Exception
    This method is called by DataSource.execute() for "update" operations. It is the appropriate override point if you wish to provide custom handling of an "update".
    Overrides:
      `executeUpdate` in class `DataSource`
    Parameters:
      `req` - The DSRequest object representing this operation
    Returns:
      A valid DSResponse
    Throws:
      `Exception` - if an error occurs during the update operation

  - ### escapeValueForFilter

    public static String escapeValueForFilter(Object value, char escapeChar)
    Escapes characters "_" and "%" with specified character in value object. Specified escape character is escaped (doubled) as well. Empty string is returned if value object is null.
    Parameters:
      `value` - `Object` Value which should be escaped.
      `escapeChar` - `char` escape character.
    Returns:
      `String` Escaped string value.

  - ### markTransactionForRollBack

    public void markTransactionForRollBack(DSResponse dsResponse)
    Sets flag that current transaction should be rolled back. If `DSResponse` is provided - sets it's status to failure.
    Parameters:
      `dsResponse` - `DSResponse` status will be set to failure if provided. Can be `null`.

  - ### freeResources

    public void freeResources(DSRequest req)
    Closes `EntityManager`. When participating in automatic transactions - closes `EntityManager` stored in `connectionHolder` object. If `connectionHolder` is not initialized (meaning we did not participate in automatic transaction) - closes current `EntityManager`.

  - ### getTransactionObjectKey

    public String getTransactionObjectKey(boolean longForm)

  - ### increaseOpCount

    public void increaseOpCount()
    Increases operations count by 1. Used to update statistics for Automatic Transactions.