![JAR search and dependency download from the Maven repository](/logo.png)
com.jk.data.dataaccess.orm.JKObjectDataAccessImpl Maven / Gradle / Ivy
/*
* Copyright 2002-2022 Dr. Jalal Kiswani.
* Email: [email protected]
* Check out https://smart-api.com for more details
*
* All the opensource projects of Dr. Jalal Kiswani are free for personal and academic use only,
* for commercial usage and support, please contact the author.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jk.data.dataaccess.orm;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import org.hibernate.CacheMode;
import org.hibernate.query.spi.QueryImplementor;
import com.jk.core.cache.JKCacheFactory;
import com.jk.core.cache.JKCacheManager;
import com.jk.core.config.JKConfig;
import com.jk.core.config.JKConstants;
import com.jk.core.context.JKContextFactory;
import com.jk.core.jpa.BaseEntity;
import com.jk.core.logging.JKLogger;
import com.jk.core.logging.JKLoggerFactory;
import com.jk.core.util.JK;
import com.jk.data.dataaccess.JKDataAccessFactory;
import com.jk.data.dataaccess.orm.meta.JKColumnWrapper;
import com.jk.data.dataaccess.orm.meta.JKSortInfo;
import com.jk.data.datasource.JKDataSource;
import com.jk.data.datasource.JKDataSourceFactory;
import com.jk.data.exceptions.JKDataAccessManyRowsException;
import jakarta.persistence.EntityManager;
// TODO: Auto-generated Javadoc
/**
* The Class JKObjectDataAccessImpl.
*/
public class JKObjectDataAccessImpl implements JKObjectDataAccess {
/** The max results. */
int maxResults = JKConfig.get().getPropertyAsInteger(JKConstants.Database.ORM_RESULTS_MAX, 1000);
/** The logger. */
JKLogger logger = JKLoggerFactory.getLogger(getClass());
/** The cache manager. */
JKCacheManager cacheManager = JKCacheFactory.getCacheManager();
/** The data source. */
private JKDataSource dataSource;
/** The entity manager. */
private EntityManager entityManager;
/** The roll back current transaction. */
private boolean rollBackCurrentTransaction;
/**
* Instantiates a new JK object data access impl.
*/
public JKObjectDataAccessImpl() {
}
/**
* Instantiates a new JK object data access impl.
*
* @param dataSourcePrefix the data source prefix
*/
public JKObjectDataAccessImpl(String dataSourcePrefix) {
this(JKDataSourceFactory.getDataSource(dataSourcePrefix));
}
/**
* Instantiates a new JK object data access impl.
*
* @param dataSource the data source
*/
public JKObjectDataAccessImpl(JKDataSource dataSource) {
this.dataSource = dataSource;
}
/**
* Insert.
*
* @param the generic type
* @param object the object
* @return the t
*/
/*
* (non-Javadoc)
*
* @see
* com.jk.db.test.dataaccess.orm.JKObjectDataAccess#insert(java.lang.Object)
*/
@Override
public T insert(T object) {
logger.debug("Insert object ({})", object.getClass().getName());
EntityManager manager = getEntityManager(true);
boolean commit = false;
try {
handleTimeStamps(object);
manager.persist(object);
manager.flush();
commit = true;
return object;
// return JKObjectUtil.getPropertyValue(object, "id");
} finally {
close(manager, commit);
logger.debug("/Insert object ({})", object.getClass().getName());
}
}
/**
* Update.
*
* @param the generic type
* @param object the object
* @return the t
*/
/*
* (non-Javadoc)
*
* @see
* com.jk.db.test.dataaccess.orm.JKObjectDataAccess#update(java.lang.Object)
*/
@Override
public T update(T object) {
logger.debug("Update object ({})", object.getClass().getName());
EntityManager manager = getEntityManager(true);
boolean commit = false;
try {
handleTimeStamps(object);
T merge = manager.merge(object);
manager.flush();
commit = true;
return merge;
} finally {
close(manager, commit);
logger.debug("/Update object ({})", object.getClass().getName());
}
}
/**
* Handle time stamps.
*
* @param the generic type
* @param object the object
*/
public void handleTimeStamps(T object) {
logger.debug("handleTimeStamps");
if (object instanceof BaseEntity) {
BaseEntity baseEntity = (BaseEntity) object;
baseEntity.setModDate(new Date());
baseEntity.setModUser(JKContextFactory.getCurrentContext().getUserName());
if (baseEntity.getCrtDate() == null) {
// for backword compatibility
baseEntity.setCrtDate(new Date());
baseEntity.setCrtUser(JKContextFactory.getCurrentContext().getUserName());
}
}
logger.debug("/handleTimeStamps");
}
/**
* Find.
*
* @param the generic type
* @param clas the clas
* @param id the id
* @return the t
*/
/*
* (non-Javadoc)
*
* @see com.jk.db.test.dataaccess.orm.JKObjectDataAccess#find(java.lang.Class,
* java.lang.Object)
*/
@Override
public T find(Class clas, Object id) {
logger.debug("Find object ({}) with id ({})", clas.getName(), id);
EntityManager manager = getEntityManager(false);
try {
return manager.find(clas, id);
} finally {
close(manager, false);
logger.debug("/Find object ({}) with id ({})", clas.getName(), id);
}
}
/**
* Delete.
*
* @param the generic type
* @param object the object
* @return the t
*/
/*
* (non-Javadoc)
*
* @see
* com.jk.db.test.dataaccess.orm.JKObjectDataAccess#delete(java.lang.Object)
*/
@Override
public T delete(T object) {
logger.debug("delete object ({})", object.getClass().getName());
EntityManager manager = getEntityManager(true);
boolean commit = false;
try {
object = manager.merge(object);
manager.remove(object);
manager.flush();
commit = true;
return object;
} finally {
close(manager, commit);
logger.debug("/delete object ({})", object.getClass().getName());
}
}
/**
* Delete.
*
* @param the generic type
* @param type the type
* @param id the id
* @return the t
*/
/*
* (non-Javadoc)
*
* @see
* com.jk.db.test.dataaccess.orm.JKObjectDataAccess#delete(java.lang.Object,
* java.lang.Class)
*/
@Override
public T delete(Class type, Object id) {
logger.debug("Delete object ({}) with id ({})", type.getName(), id);
EntityManager manager = getEntityManager(true);
boolean commit = false;
try {
T object = (T) manager.find(type, id);
manager.remove(object);
manager.flush();
commit = true;
return object;
} finally {
close(manager, commit);
logger.debug("/Delete object ({}) with id ({})", type.getName(), id);
}
}
/**
* Gets the list.
*
* @param the generic type
* @param clas the clas
* @return the list
*/
/*
* (non-Javadoc)
*
* @see
* com.jk.db.test.dataaccess.orm.JKObjectDataAccess#getList(java.lang.Class)
*/
@Override
public List getList(Class clas) {
logger.debug("getList ({}) ", clas.getName());
return getList(clas, null);
}
/**
* Gets the list and cache.
*
* @param the generic type
* @param clas the clas
* @return the list and cache
*/
@Override
public List getListAndCache(Class clas) {
logger.debug("getListAndCache ({}) ", clas.getName());
String key = clas.getName()+"-list";
List list = cacheManager.get(key, List.class);
if(list!=null) {
logger.debug("List with key ({}) found in cache", key);
}else {
list=getList(clas, null);
cacheManager.cache(key, list, List.class);
}
return list;
}
/**
* Gets the list.
*
* @param the generic type
* @param clas the clas
* @param paramters the paramters
* @return the list
*/
/*
* (non-Javadoc)
*
* @see
* com.jk.db.test.dataaccess.orm.JKObjectDataAccess#getList(java.lang.Class,
* java.util.Map)
*/
@Override
public List getList(Class clas, Map paramters) {
logger.debug("getList for entity ({}) with paramters ({}) ", clas.getName(), paramters);
// EntityManager manager = getEntityManager();
try {
StringBuffer buf = new StringBuffer("SELECT c FROM ".concat(clas.getSimpleName()).concat(" c "));
buf.append(" WHERE 1=1 ");
if (paramters != null) {
Set keySet = paramters.keySet();
int counter = 1;
for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
String paramName = (String) iterator.next();
buf.append(String.format(" AND c.%s=?%d", paramName, counter++));
}
// TODO : check the paramters for order
return executeQuery(clas, buf.toString(), paramters.values().toArray());
}
return executeQuery(clas, buf.toString());
} finally {
logger.debug("/getList for entity ({}) with paramters ({}) ", clas.getName(), paramters);
// close(manager, true);
}
}
/**
* Execute query.
*
* @param the generic type
* @param clas the clas
* @param queryString the query string
* @param paramters the paramters
* @return the list
*/
@Override
public List executeQuery(final Class clas, final String queryString, final Object... paramters) {
logger.debug("executeQuery for class ({}) with query ({}) with params ({})", clas.getName(), queryString,
Arrays.toString(paramters));
EntityManager em = getEntityManager(false);
try {
QueryImplementor query = (QueryImplementor) em.createQuery(queryString, clas);
if (JKConfig.get().getPropertyAsBoolean("jk.data.jpa.query.cache", true)) {
query.setCacheable(true);
query.setCacheMode(CacheMode.NORMAL);
query.setCacheRegion(queryString + Arrays.toString(paramters));
}
for (int i = 0; i < paramters.length; i++) {
Object object = paramters[i];
query.setParameter(i + 1, object);
}
query.setMaxResults(maxResults);
logger.debug("executeQuery query.getResultList() for class ({}) with query ({}) with params ({})",
clas.getName(), queryString, Arrays.toString(paramters));
List resultList = query.getResultList();
if (resultList == null) {
return new Vector<>();
}
return resultList;
} finally {
logger.debug("/executeQuery for class ({}) with query ({}) with params ({})", clas.getName(), queryString,
Arrays.toString(paramters));
close(em, true);
}
}
/**
* Gets the entity manager.
*
* @param withTrx the with trx
* @return the entity manager
*/
protected EntityManager getEntityManager(boolean withTrx) {
logger.debug("getEntityManager with trx({})", withTrx);
EntityManager manager = null;
if (this.entityManager != null) {
manager = this.entityManager;
} else {
manager = getDataSource().createEntityManager();
if (withTrx) {
manager.getTransaction().begin();
}
}
logger.debug("/getEntityManager with trx({})", withTrx);
return manager;
}
/**
* Gets the data source.
*
* @return the data source
*/
protected JKDataSource getDataSource() {
logger.debug("getDataSource()");
JKDataSource dataSource = this.dataSource;
if (this.dataSource == null) {
dataSource = JKDataAccessFactory.getDefaultDataSource();
}
logger.debug("/getDataSource()");
return dataSource;
}
/**
* Close.
*
* @param manager the manager
* @param commit the commit
*/
private void close(EntityManager manager, boolean commit) {
logger.debug("closeEntityManager(commit={})", commit);
if (entityManager == manager) {
if (!commit) {
rollBackCurrentTransaction = true;
}
} else {
getDataSource().close(manager, commit);
}
logger.debug("/closeEntityManager(commit={})", commit);
// try {
// if (manager.isOpen() && manager.isJoinedToTransaction()) {
// if (commit) {
// manager.getTransaction().commit();
// } else {
// manager.getTransaction().rollback();
// }
// }
// } finally {
// }
}
/**
* Gets the query order.
*
* @param clas the clas
* @return the query order
* @throws NoSuchMethodException the no such method exception
* @throws IllegalAccessException the illegal access exception
* @throws InvocationTargetException the invocation target exception
*/
protected String getQueryOrder(final Class extends JKEntity> clas)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
logger.debug("getQueryOrder({})", clas.getName());
JK.fixMe("check this");
Method method = clas.getMethod("getSortInfo", Class.class);
JKSortInfo info = (JKSortInfo) method.invoke(null, clas);
StringBuffer buf2 = new StringBuffer();
if (info != null) {
buf2.append("ORDER BY ");
JKColumnWrapper col = (JKColumnWrapper) info.column();
buf2.append("c." + col.getFieldName());
buf2.append(" " + info.sortOrder().toString());
}
logger.debug("/getQueryOrder({})", clas.getName());
return buf2.toString();
}
/**
* Find single entity.
*
* @param the generic type
* @param clas the clas
* @param queryString the query string
* @param paramters the paramters
* @return the t
*/
public T findSingleEntity(Class clas, final String queryString, final Object... paramters) {
logger.debug("findSingleEntity(query={}, paramters{})", queryString, paramters);
List list = executeQuery(clas, queryString, paramters);
try {
if (list.size() == 0) {
return null;
}
if (list.size() == 1) {
return list.get(0);
}
throw new JKDataAccessManyRowsException(queryString, paramters);
} finally {
logger.debug("/findSingleEntity(query={}, paramters{})", queryString, paramters);
}
}
/**
* Gets the first record.
*
* @param the generic type
* @param clas the clas
* @return the first record
*/
// ///////////////////////////////////////////////////////////////////////////////////////
public T getFirstRecord(Class clas) {
logger.debug("getFirstRecord({})", clas.getName());
List all = getList(clas);
T record = null;
if (all.size() > 0) {
record = all.get(0);
}
logger.debug("/getFirstRecord({})", clas.getName());
return record;
}
/**
* Find by field name.
*
* @param the generic type
* @param clas the clas
* @param fieldName the field name
* @param value the value
* @return the list
*/
@Override
// ///////////////////////////////////////////////////////////////////////////////////////
public List findByFieldName(Class clas, String fieldName, Object value) {
logger.debug("findByFieldName for class ({}) with field ({}) and value ({})", clas.getSimpleName(), fieldName,
value);
String query = String.format("SELECT c FROM %s c WHERE c.%s=?1", clas.getSimpleName(), fieldName);
try {
return executeQuery(clas, query, value);
} finally {
logger.debug("/findByFieldName for class ({}) with field ({}) and value ({})", clas.getSimpleName(),
fieldName, value);
}
}
/**
* Insert or update.
*
* @param the generic type
* @param object the object
* @return the t
*/
@Override
public T insertOrUpdate(T object) {
logger.debug("insertOrUpdate({})", object.getClass().getName());
EntityManager manager = getEntityManager(true);
boolean commit = false;
try {
handleTimeStamps(object);
T merge = manager.merge(object);
commit = true;
return merge;
} finally {
close(manager, commit);
logger.debug("insertOrUpdate({})", object.getClass().getName());
}
}
/**
* Find one by field name.
*
* @param the generic type
* @param clas the clas
* @param fieldName the field name
* @param fieldValue the field value
* @return the t
*/
@Override
public T findOneByFieldName(Class clas, String fieldName, Object fieldValue) {
logger.debug("findOneByFieldName(class={},fieldName={},value={})", clas, fieldName, fieldValue);
try {
List list = findByFieldName(clas, fieldName, fieldValue);
if (list.size() == 0) {
return null;
}
if (list.size() > 1) {
JK.error("Results returned more than one row");
}
return list.get(0);
} finally {
logger.debug("/findOneByFieldName(class={},fieldName={},value={})", clas, fieldName, fieldValue);
}
}
/**
* Sets the max results.
*
* @param maxResults the new max results
*/
@Override
public void setMaxResults(int maxResults) {
this.maxResults = maxResults;
}
/**
* Detach.
*
* @param model the model
*/
@Override
public void detach(Object model) {
logger.debug("detach({})",model);
getEntityManager(false).detach(model);
logger.debug("/detach({})",model);
}
/**
* Clone.
*
* @param the generic type
* @param model the model
* @return the t
*/
@Override
public T clone(T model) {
logger.debug("clone({})", model);
detach(model);
logger.debug("/clone({})", model);
return model;
}
/**
* Start transaction.
*/
@Override
public void startTransaction() {
logger.debug("startTransaction()");
entityManager = getDataSource().createEntityManager();
entityManager.getTransaction().begin();
logger.debug("/startTransaction()");
}
/**
* Close transaction.
*
* @param commit the commit
*/
@Override
public void closeTransaction(boolean commit) {
logger.debug("closeTransaction({})", commit);
if (this.entityManager == null) {
JK.exception("EntityManager shouldnt be null at this point");
}
try {
getDataSource().close(entityManager, rollBackCurrentTransaction ? rollBackCurrentTransaction : commit);
} finally {
this.entityManager = null;
this.rollBackCurrentTransaction = false;
}
logger.debug("/closeTransaction({})", commit);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy