Class 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:
  • 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:
    • 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:
    • 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:
    • 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:
    • 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:
    • 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:
    • 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:
    • 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.