Class BaseMyBatisGenericDao<T extends net.solarnetwork.dao.Entity<PK>,PK extends Serializable>

java.lang.Object
org.springframework.dao.support.DaoSupport
org.mybatis.spring.support.SqlSessionDaoSupport
net.solarnetwork.central.dao.mybatis.support.BaseMyBatisDao
net.solarnetwork.central.dao.mybatis.support.BaseMyBatisGenericDao<T,PK>
Type Parameters:
T - The entity type this DAO supports.
PK - The primary key type this DAO supports.
All Implemented Interfaces:
GenericDao<T,PK>, org.springframework.beans.factory.InitializingBean
Direct Known Subclasses:
BaseMyBatisFilterableDao, MyBatisSolarNodeMetadataDao

public abstract class BaseMyBatisGenericDao<T extends net.solarnetwork.dao.Entity<PK>,PK extends Serializable> extends BaseMyBatisDao implements GenericDao<T,PK>
Base implementation of GenericDao using MyBatis via SqlSessionDaoSupport.

The default configuration of this class allows implementations to be used with minimal configuration, by following some simple naming conventions on MyBatis query names. The queryForId, queryForAll, insert, update, and delete query names all follow a pattern using the name of the domain class as a parameter.

For example, if the domain class managed by this DAO is some.package.Foo then the default query names used by this class will be:

  • get-Foo-by-id
  • findall-Foo
  • insert-Foo
  • update-Foo
  • delete-Foo

The handleRelation(Long, List, Class, Map) can be used by extending classes to manage a to-many type relationship. The relationQueryForParent, relationInsert, relationUpdate, and relationDelete query names follow the same pattern as above, with the relation domain class name appended at the end. For example, if the relation domain class was some.package.Bar then the default relationship query names used by this class will be:

  • findall-Foo-Bar
  • insert-Foo-Bar
  • update-Foo-Bar
  • delete-Foo-Bar

The ID_PROPERTY, INDEX_PROPERTY, and BEAN_OBJECT_PROPERTY keys will be passed to the query as needed to manage the related entity list.

The configurable properties of this class are:

domainClass
The implementation Class managed by this DAO.
queryForId
The name of the MyBatis SQL query to load an entity based on its primary key (a Long). Defaults to get-DomainClass-for-id where DatumClass is the simple name of the configured domainClass.
queryForAll
The name of the MyBatis SQL query to return a list of entities, supporting a custom sort order. Defaults to findall-DomainClass where DatumClass is the simple name of the configured domainClass.
insert
The name of the MyBatis SQL query to insert a new entity into the database. Defaults to insert-DomainClass where DatumClass is the simple name of the configured domainClass.
update
The name of the MyBatis SQL query to update an existing entity in the database. Defaults to update-DomainClass where DatumClass is the simple name of the configured domainClass.
delete
The name of the MyBatis SQL query to delete an existing entity from the database. Defaults to delete-DomainClass where DatumClass is the simple name of the configured domainClass.
  • Field Details

  • Constructor Details

    • BaseMyBatisGenericDao

      public BaseMyBatisGenericDao(Class<? extends T> domainClass, Class<? extends PK> pkClass)
      Constructor.
      Parameters:
      domainClass - the domain class
      pkClass - the primary key class
  • Method Details

    • getObjectType

      public Class<? extends T> getObjectType()
      Description copied from interface: GenericDao
      Get the class supported by this Dao.
      Specified by:
      getObjectType in interface GenericDao<T extends net.solarnetwork.dao.Entity<PK>,PK extends Serializable>
      Returns:
      class
    • getPrimaryKeyType

      public Class<? extends PK> getPrimaryKeyType()
      Get the primary key type used by this DAO.
      Returns:
      the primary key type
    • get

      public T get(PK id)
      Description copied from interface: GenericDao
      Get a persisted domain object by its primary key.
      Specified by:
      get in interface GenericDao<T extends net.solarnetwork.dao.Entity<PK>,PK extends Serializable>
      Parameters:
      id - the primary key to retrieve
      Returns:
      the domain object
    • getAll

      public List<T> getAll(List<net.solarnetwork.domain.SortDescriptor> sortDescriptors)
      Description copied from interface: GenericDao
      Get a list of persisted domain objects, optionally sorted in some way.

      The sortDescriptors parameter can be null, in which case the sort order is not defined and implementation specific.

      Specified by:
      getAll in interface GenericDao<T extends net.solarnetwork.dao.Entity<PK>,PK extends Serializable>
      Parameters:
      sortDescriptors - list of sort descriptors to sort the results by
      Returns:
      list of all persisted domain objects, or empty list if none available
    • store

      public PK store(T datum)
      Description copied from interface: GenericDao
      Persist the domainObject object into database, creating or updating as appropriate.
      Specified by:
      store in interface GenericDao<T extends net.solarnetwork.dao.Entity<PK>,PK extends Serializable>
      Parameters:
      datum - the domain object so store
      Returns:
      the primary key of the stored object
    • handleAssignedPrimaryKeyStore

      protected PK handleAssignedPrimaryKeyStore(T datum)
      Supporting method for handling the store(Entity) method for entities that use assigned primary keys, where the default logic of handling insert versus update will not work.

      This implementation attempts to update the given entity first. If that does not actually update any rows, preprocessInsert(Entity) is called, followed by an insert.

      Parameters:
      datum - the datum to store
      Returns:
      the primary key
    • preprocessInsert

      protected void preprocessInsert(T datum)
      Process a new unsaved entity for persisting.

      This implementation will set the value of the created bean property of the datum instance to the current time if Entity.getCreated() is null. Extending classes may want to extend or modify this behavior.

      Parameters:
      datum - the entity to be persisted
    • handleUpdate

      protected PK handleUpdate(T datum)
      Process the update of a persisted entity.

      This implementation merely calls SqlSession.update(String, Object) using the getUpdate() SqlMap.

      Parameters:
      datum - the datum to update
      Returns:
      Identity.getId()
    • handleInsert

      protected PK handleInsert(T datum)
      Process the insert of a persisted entity.

      This implementation calls SqlSession.insert(String, Object) using the getInsert() SqlMap.

      Parameters:
      datum - the datum to insert
      Returns:
      the result of the insert statement
    • delete

      public void delete(T domainObject)
      Description copied from interface: GenericDao
      Remove an object from persistent storage in the database.
      Specified by:
      delete in interface GenericDao<T extends net.solarnetwork.dao.Entity<PK>,PK extends Serializable>
      Parameters:
      domainObject - the domain object to delete
    • handleRelation

      protected <E> void handleRelation(Long parentId, List<E> newList, Class<? extends E> relationClass, Map<String,?> additionalProperties)
      Insert, update, and delete domain object list related to the entity managed by this DAO.

      This method will use the relationQueryForParent, relationInsert, relationUpdate, and relationDelete query names configured on this class to persist a set of related objects to a single parent entity. The related objects are not assumed to have surrogate primary keys.

      This method will pass the following query properties:

      ID_PROPERTY
      The parentId value, passed to all queries.
      INDEX_PROPERTY
      The list index, starting at zero. This defines the ordering of the related objects. Note the relationDelete query must support not having this property set, which signals that all related objects should be deleted.
      BEAN_OBJECT_PROPERTY
      The related object to persist, passed to relationInsert and relationUpdate queries.

      Note that this method does not follow a pattern of deleting all related objects and then re-inserting objects. If there is a unique constraint defined on some columns, the constraint should be configured to defer the constraint check until after the end of the transaction. Otherwise constraint violations can occur while making the updates.

      Type Parameters:
      E - the related object type
      Parameters:
      parentId - the ID of the parent entity
      newList - the list of related objects to persist (may be null)
      relationClass - the Class of the related object
      additionalProperties - optional properties to pass to all queries
    • handleRelation

      protected <E extends net.solarnetwork.domain.Identity<Long>> void handleRelation(Long parentId, E newObject, Class<? extends E> relationClass, Map<String,?> additionalProperties)
      Insert, update, and delete domain object related to the entity managed by this DAO.

      This method will use the relationObjectQueryForParent, relationInsert, relationUpdate, and relationDelete query names configured on this class to persist a related object to a single parent entity. The related object is not assumed to have surrogate primary keys.

      This method will pass the following query properties:

      ID_PROPERTY
      The parentId value, passed to all queries.
      BEAN_OBJECT_PROPERTY
      The related object to persist, passed to relationInsert and relationUpdate and relationDelete queries.
      Type Parameters:
      E - the related object type
      Parameters:
      parentId - the ID of the parent entity
      newObject - the related object to persist (may be null)
      relationClass - the Class of the related object
      additionalProperties - optional properties to pass to all queries
    • handleChildRelation

      protected <E extends net.solarnetwork.domain.Identity<Long>> Long handleChildRelation(T parent, E child, Class<? extends E> relationClass)
      Insert, update, and delete domain object child of the entity managed by this DAO.

      This method will use the relationObjectQueryForParent, childInsert, childUpdate, and childDelete query names configured on this class to persist a related object to a single parent entity.

      This method will pass the following query objects:

      relationObjectQueryForParent
      A Long, taken from ID value of the parent.
      childDelete
      A Long, from the ID value of the child.
      childInsert
      The child object. This query is expected to return the child's primary key in the form of a Long object.
      childUpdate
      The child object.
      Type Parameters:
      E - the related object type
      Parameters:
      parent - the parent entity
      child - the child object to persist (may be null)
      relationClass - the Class of the related object
      Returns:
      the child entity's primary key
    • execute

      protected <R> R execute(SqlSessionCallback<R> callback, Object errorObject)
      Execute a task with a SqlSessionCallback, providing standardized error message handling. This method will catch runtime exceptions and attempt to map those to message codes. If the exception can be mapped, a new ValidationException will be thrown instead.
      Type Parameters:
      R - the result object type
      Parameters:
      callback - the callback
      errorObject - the root validation error object
      Returns:
      the result of SqlSessionCallback.doWithSqlSession(org.apache.ibatis.session.SqlSession)
      See Also:
    • mapSqlMapException

      protected RuntimeException mapSqlMapException(RuntimeException e, Object errorObject)
      Attempt to map a runtime, SQL related exception to some friendlier exception.
      Parameters:
      e - the original exception
      errorObject - a validation error object
      Returns:
      an exception, never null and might be the exception instance passed in
    • getMemberDomainKey

      protected String getMemberDomainKey(Class<?> memberClass)
      Get a "domain" for member queries.

      This returns a composite string based from getDomainClass() and the memberClass passed in.

      Parameters:
      memberClass - the member class type
      Returns:
      domain key
    • spaceAppend

      protected final boolean spaceAppend(String value, StringBuilder buf)
      Append to a space-delimited string buffer.

      This is designed with full-text search in mind, for building up a query string.

      Parameters:
      value - the value to append if not empty
      buf - the buffer to append to
      Returns:
      true if value was appended to buf
    • getQueryForId

      public String getQueryForId()
    • setQueryForId

      public void setQueryForId(String queryForId)
    • getInsert

      public String getInsert()
    • setInsert

      public void setInsert(String insert)
    • getUpdate

      public String getUpdate()
    • setUpdate

      public void setUpdate(String update)
    • getDomainClass

      public Class<? extends T> getDomainClass()
    • getQueryForAll

      public String getQueryForAll()
    • setQueryForAll

      public void setQueryForAll(String queryForAll)
    • getDelete

      public String getDelete()
    • setDelete

      public void setDelete(String delete)
    • getRelationQueryForParent

      public String getRelationQueryForParent()
    • setRelationQueryForParent

      public void setRelationQueryForParent(String relationQueryForParent)
    • getRelationInsert

      public String getRelationInsert()
    • setRelationInsert

      public void setRelationInsert(String relationInsert)
    • getRelationUpdate

      public String getRelationUpdate()
    • setRelationUpdate

      public void setRelationUpdate(String relationUpdate)
    • getRelationDelete

      public String getRelationDelete()
    • setRelationDelete

      public void setRelationDelete(String relationDelete)
    • getRelationObjectQueryForParent

      public String getRelationObjectQueryForParent()
    • setRelationObjectQueryForParent

      public void setRelationObjectQueryForParent(String relationObjectQueryForParent)
    • getChildInsert

      public String getChildInsert()
    • setChildInsert

      public void setChildInsert(String childInsert)
    • getChildUpdate

      public String getChildUpdate()
    • setChildUpdate

      public void setChildUpdate(String childUpdate)
    • getChildDelete

      public String getChildDelete()
    • setChildDelete

      public void setChildDelete(String childDelete)
    • getMessageSource

      public org.springframework.context.MessageSource getMessageSource()
    • setMessageSource

      public void setMessageSource(org.springframework.context.MessageSource messageSource)