/*******************************************************************************
 * Copyright 2019 2Fi Business Solutions Ltd.
 *
 * This code is part of the Core project.
 *
 * This code is copyrighted. Under no circumstances should any party, people,
 * or organization should redistribute any portions of this code in any form,
 * either verbatim or through electronic media, to any third parties, unless
 * under explicit written permission by 2Fi Business Solutions Ltd.
 ******************************************************************************/
package com.ffii.core.dao;

import java.io.Serializable;
import java.util.List;

import org.springframework.orm.hibernate5.HibernateTemplate;

/**
 * Hibernate DAO interface. For use with business services to perform actual operations.
 *
 * @param <T>
 *            The class this DAO is taking care of.
 * @param <PK>
 *            The type of the primary key of class instances.
 *
 * @author Patrick
 */
public interface IHibernateDao<T extends Serializable, PK extends Serializable> {

	/**
	 * Returns the underlying {@link HibernateTemplate}
	 */
	public HibernateTemplate getHibernateTemplate();

	/**
	 * Saves the instance to the database.
	 *
	 * @param instance
	 *            the object instance to save
	 *
	 * @return the object instance's primary key in database
	 */
	public PK save(T instance);

	/**
	 * Saves the instance to the database without setting the created/updated fields.
	 *
	 * @param instance
	 *            the object instance to save
	 *
	 * @return the object instance's primary key in database
	 */
	public PK saveAs(T instance);

	/**
	 * Updates the record in the database with the given instance.
	 *
	 * @param instance
	 *            modified object instance
	 */
	public void update(T instance);

	/**
	 * Saves or updates the record in the database with the given instance.
	 *
	 * @param instance
	 *            new or modified object instance
	 *
	 * @return the object instance's primary key in database
	 */
	public PK saveOrUpdate(T instance);

	/**
	 * Deletes the object instance from the database.
	 *
	 * @param instance
	 *            the object instance to remove
	 */
	public boolean delete(T instance);

	/**
	 * Remove a collection of instances from the database.
	 *
	 * @param instances
	 *            The object instances to remove
	 */
	public void deleteAll(List<T> instances);

	/**
	 * Finds the object with the specified identity from the database.
	 *
	 * @param id
	 *            the object's primary key in database
	 *
	 * @return the mapped object instance from the database
	 */
	public T find(PK id);

	/**
	 * Finds the object using the specified query (HQL) and arguments from the database.
	 *
	 * @param queryString
	 *            the query string using HQL
	 * @param args
	 *            variable number of arguments to pass to the query. Note you must have the exact number of arguments as specified in the query.
	 *
	 * @return the object instance from the database
	 */
	public T findByQuery(String queryString, Serializable... args);

	/**
	 * Returns a {@code List} of {@code Object}s using the specified query (HQL) and arguments from the database.
	 *
	 * @param queryString
	 *            the query string using HQL
	 * @param args
	 *            variable number of arguments to pass to the query. Note you must have the exact number of arguments as specified in the query.
	 *
	 * @return {@code List} of object instances from the database
	 */
	public List<T> listByQuery(String queryString, Serializable... args);

	public void flush();

}
