Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.impetus.client.rdbms.HibernateClient Maven / Gradle / Ivy
/*******************************************************************************
* * Copyright 2012 Impetus Infotech.
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * 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.impetus.client.rdbms;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PersistenceException;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.StatelessSession;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.impetus.client.rdbms.query.RDBMSQuery;
import com.impetus.kundera.client.Client;
import com.impetus.kundera.client.ClientBase;
import com.impetus.kundera.client.EnhanceEntity;
import com.impetus.kundera.db.RelationHolder;
import com.impetus.kundera.index.IndexManager;
import com.impetus.kundera.metadata.KunderaMetadataManager;
import com.impetus.kundera.metadata.MetadataUtils;
import com.impetus.kundera.metadata.model.ClientMetadata;
import com.impetus.kundera.metadata.model.EntityMetadata;
import com.impetus.kundera.metadata.model.Relation;
import com.impetus.kundera.metadata.model.attributes.AbstractAttribute;
import com.impetus.kundera.persistence.EntityReader;
import com.impetus.kundera.persistence.EntityReaderException;
import com.impetus.kundera.persistence.context.jointable.JoinTableData;
import com.impetus.kundera.property.PropertyAccessException;
import com.impetus.kundera.property.PropertyAccessor;
import com.impetus.kundera.property.PropertyAccessorFactory;
import com.impetus.kundera.property.PropertyAccessorHelper;
import com.impetus.kundera.proxy.ProxyHelper;
/**
* The Class HibernateClient.
*
* @author vivek.mishra
*/
public class HibernateClient extends ClientBase implements Client
{
/** The sf. */
private SessionFactory sf;
/** The s. */
private StatelessSession s;
/** The reader. */
private EntityReader reader;
private Map puProperties;
/** The Constant log. */
private static final Logger log = LoggerFactory.getLogger(HibernateClient.class);
/**
* Instantiates a new hibernate client.
*
* @param persistenceUnit
* the persistence unit
* @param indexManager
* the index manager
* @param reader
* the reader
* @param puProperties
*/
public HibernateClient(final String persistenceUnit, IndexManager indexManager, EntityReader reader,
SessionFactory sf, Map puProperties, final ClientMetadata clientMetadata)
{
this.sf = sf;
// TODO . once we clear this persistenceUnit stuff we need to simply
// modify this to have a properties or even pass an EMF!
this.persistenceUnit = persistenceUnit;
this.indexManager = indexManager;
this.reader = reader;
this.puProperties = puProperties;
this.clientMetadata = clientMetadata;
}
/*
* (non-Javadoc)
*
* @see com.impetus.kundera.client.Client#close()
*/
@Override
public void close()
{
this.indexManager.flush();
if (s != null)
{
s.close();
s = null;
}
puProperties = null;
}
/*
* (non-Javadoc)
*
* @see com.impetus.kundera.client.Client#delete(java.lang.Object,
* java.lang.Object)
*/
@Override
public void delete(Object entity, Object pKey)
{
s = getSessionFactory().openStatelessSession();
Transaction tx = s.beginTransaction();
s.delete(entity);
tx.commit();
EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(entity.getClass());
if (!MetadataUtils.useSecondryIndex(getClientMetadata()))
{
getIndexManager().remove(metadata, entity, pKey.toString());
}
}
/*
* (non-Javadoc)
*
* @see com.impetus.kundera.client.Client#find(java.lang.Class,
* java.lang.String)
*/
@Override
public Object find(Class clazz, Object key)
{
EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(getPersistenceUnit(), clazz);
if (s == null)
{
s = getSessionFactory().openStatelessSession();
//
// s.beginTransaction();
}
Object result = null;
try
{
result = s.get(clazz, getKey(key, (Field) entityMetadata.getIdAttribute().getJavaMember()));
}
catch (Exception e)
{
log.info(e.getMessage());
}
return result;
}
/*
* (non-Javadoc)
*
* @see com.impetus.kundera.client.Client#find(java.lang.Class,
* java.lang.String[])
*/
@Override
public List findAll(Class arg0, String[] columnsToSelect, Object... arg1)
{
// TODO: Vivek correct it. unfortunately i need to open a new session
// for each finder to avoid lazy loading.
List objs = new ArrayList();
Session s = getSessionFactory().openSession();
Transaction tx = s.beginTransaction();
EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(getPersistenceUnit(), arg0);
Object[] pKeys = getDataType(entityMetadata, arg1);
String id = ((AbstractAttribute) entityMetadata.getIdAttribute()).getJPAColumnName();
Criteria c = s.createCriteria(arg0);
c.add(Restrictions.in(id, pKeys));
return c.list();
}
@Override
public List find(Class entityClass, Map embeddedColumnMap)
{
return null;
}
@Override
protected void onPersist(EntityMetadata metadata, Object entity, Object id, List relationHolders)
{
boolean proxyRemoved = removeKunderaProxies(metadata, entity, relationHolders);
Transaction tx = null;
s = getSessionFactory().openStatelessSession();
tx = s.beginTransaction();
try
{
if (!isUpdate)
{
id = s.insert(entity);
// Update foreign Keys
updateForeignKeys(metadata, id, relationHolders);
tx.commit();
}
else
{
s.update(entity);
if (proxyRemoved)
{
updateForeignKeys(metadata, id, relationHolders);
}
tx.commit();
}
}
// TODO: Bad code, get rid of these exceptions, currently necessary for
// handling many to one case
catch (org.hibernate.exception.ConstraintViolationException e)
{
s.update(entity);
log.info(e.getMessage());
tx.commit();
}
catch (HibernateException e)
{
log.error("Error while persisting object of {}", metadata.getEntityClazz(), e);
throw new PersistenceException(e);
}
}
/**
* Inserts records into JoinTable
*/
@Override
public void persistJoinTable(JoinTableData joinTableData)
{
String schemaName = KunderaMetadataManager.getEntityMetadata(joinTableData.getEntityClass()).getSchema();
String joinTableName = joinTableData.getJoinTableName();
String joinColumnName = joinTableData.getJoinColumnName();
String invJoinColumnName = joinTableData.getInverseJoinColumnName();
Map> joinTableRecords = joinTableData.getJoinTableRecords();
for (Object key : joinTableRecords.keySet())
{
Set values = joinTableRecords.get(key);
insertRecordInJoinTable(schemaName, joinTableName, joinColumnName, invJoinColumnName, key, values);
}
}
@Override
public List getColumnsById(String schemaName, String joinTableName, String joinColumnName,
String inverseJoinColumnName, Object parentId, Class columnJavaType)
{
StringBuffer sqlQuery = new StringBuffer();
sqlQuery.append("SELECT ").append(inverseJoinColumnName).append(" FROM ")
.append(getFromClause(schemaName, joinTableName)).append(" WHERE ").append(joinColumnName).append("='")
.append(parentId).append("'");
Session s = getSessionFactory().openSession();
Transaction tx = s.beginTransaction();
SQLQuery query = s.createSQLQuery(sqlQuery.toString());
List foreignKeys = new ArrayList();
foreignKeys = query.list();
tx.commit();
return foreignKeys;
}
/*
* (non-Javadoc)
*
* @see com.impetus.kundera.client.Client#findIdsByColumn(java.lang.String,
* java.lang.String, java.lang.String, java.lang.Object, java.lang.Class)
*/
@Override
public Object[] findIdsByColumn(String schemaName, String tableName, String pKeyName, String columnName,
Object columnValue, Class entityClazz)
{
String childIdStr = (String) columnValue;
StringBuffer sqlQuery = new StringBuffer();
sqlQuery.append("SELECT ").append(pKeyName).append(" FROM ").append(getFromClause(schemaName, tableName))
.append(" WHERE ").append(columnName).append("='").append(childIdStr).append("'");
Session s = getSessionFactory().openSession();
// Transaction tx = s.beginTransaction();
SQLQuery query = s.createSQLQuery(sqlQuery.toString());
List primaryKeys = new ArrayList();
primaryKeys = query.list();
if (primaryKeys != null && !primaryKeys.isEmpty())
{
return primaryKeys.toArray(new Object[0]);
}
return null;
}
/*
* (non-Javadoc)
*
* @see com.impetus.kundera.client.Client#deleteByColumn(java.lang.String,
* java.lang.String, java.lang.Object)
*/
public void deleteByColumn(String schemaName, String tableName, String columnName, Object columnValue)
{
StringBuffer query = new StringBuffer();
query.append("DELETE FROM ").append(getFromClause(schemaName, tableName)).append(" WHERE ").append(columnName)
.append("=").append("'").append(columnValue).append("'");
s = getStatelessSession();
Transaction tx = s.beginTransaction();
s.createSQLQuery(query.toString()).executeUpdate();
tx.commit();
}
/**
* Insert record in join table.
*
* @param joinTableName
* the join table name
* @param joinColumnName
* the join column name
* @param inverseJoinColumnName
* the inverse join column name
* @param relMetadata
* the rel metadata
* @param parentId
* the parent id
* @param schema
* @param child
* the child
*/
private void insertRecordInJoinTable(String schemaName, String joinTableName, String joinColumnName,
String inverseJoinColumnName, Object parentId, Set childrenIds)
{
s = getSessionFactory().openStatelessSession();
Transaction tx = s.beginTransaction();
for (Object childId : childrenIds)
{
StringBuffer query = new StringBuffer();
// write an update query
Object[] existingRowIds = findIdsByColumn(schemaName, joinTableName, joinColumnName, inverseJoinColumnName,
(String) childId, null);
boolean joinTableRecordsExists = false;
if (existingRowIds != null && existingRowIds.length > 0)
{
for (Object o : existingRowIds)
{
if (o.toString().equals(parentId.toString()))
{
joinTableRecordsExists = true;
break;
}
}
}
if (!joinTableRecordsExists)
{
query.append("INSERT INTO ").append(getFromClause(schemaName, joinTableName)).append("(")
.append(joinColumnName).append(",").append(inverseJoinColumnName).append(")")
.append(" VALUES('").append(parentId).append("','").append(childId).append("')");
s.createSQLQuery(query.toString()).executeUpdate();
}
}
tx.commit();
}
/**
* Gets the session instance.
*
* @return the session instance
*/
private StatelessSession getStatelessSession()
{
return s != null ? s : getSessionFactory().openStatelessSession();
}
/**
* Find.
*
* @param nativeQuery
* the native fquery
* @param relations
* the relations
* @param m
* the m
* @return the list
*/
public List find(String nativeQuery, List relations, EntityMetadata m)
{
List result = new ArrayList();
s = getSessionFactory().openStatelessSession();
s.beginTransaction();
SQLQuery q = s.createSQLQuery(nativeQuery).addEntity(m.getEntityClazz());
if (relations != null)
{
for (String r : relations)
{
Relation rel = m.getRelation(m.getFieldName(r));
String name = MetadataUtils.getMappedName(m, m.getRelation(r));
if (!((AbstractAttribute) m.getIdAttribute()).getJPAColumnName().equalsIgnoreCase(
name != null ? name : r)
&& rel != null
&& !rel.getProperty().isAnnotationPresent(ManyToMany.class)
&& !rel.getProperty().isAnnotationPresent(OneToMany.class)
&& (rel.getProperty().isAnnotationPresent(OneToOne.class)
&& StringUtils.isBlank(rel.getMappedBy()) || rel.getProperty().isAnnotationPresent(
ManyToOne.class)))
{
q.addScalar(name != null ? name : r);
}
}
}
s.getTransaction().commit();
return q.list();
}
/*
* (non-Javadoc)
*
* @see com.impetus.kundera.client.Client#find(java.lang.String,
* java.lang.String, com.impetus.kundera.metadata.model.EntityMetadata)
*/
public List findByRelation(String colName, Object colValue, Class entityClazz)
{
EntityMetadata m = KunderaMetadataManager.getEntityMetadata(entityClazz);
String tableName = m.getTableName();
String aliasName = "_" + tableName;
StringBuilder queryBuilder = new StringBuilder("Select ");
// queryBuilder.append(aliasName);
queryBuilder.append("* ");
queryBuilder.append("From ");
queryBuilder.append(getFromClause(m.getSchema(), tableName));
queryBuilder.append(" ");
// queryBuilder.append(aliasName);
queryBuilder.append(" Where ");
queryBuilder.append(colName);
queryBuilder.append(" = ");
queryBuilder.append("'");
queryBuilder.append(colValue);
queryBuilder.append("'");
s = getSessionFactory().openStatelessSession();
s.beginTransaction();
List results = find(queryBuilder.toString(), m.getRelationNames(), m);
return populateEnhanceEntities(m, m.getRelationNames(), results);
// SQLQuery q =
// s.createSQLQuery(queryBuilder.toString()).addEntity(m.getEntityClazz());
// // tx.commit();
// return q.list();
}
/*
* (non-Javadoc)
*
* @see com.impetus.kundera.client.Client#getReader()
*/
public EntityReader getReader()
{
return reader;
}
/*
* (non-Javadoc)
*
* @see com.impetus.kundera.client.Client#getQueryImplementor()
*/
@Override
public Class getQueryImplementor()
{
return RDBMSQuery.class;
}
/**
* Gets the key.
*
* @param pKey
* the key
* @param f
* the f
* @return the key
*/
private Serializable getKey(Object pKey, Field f)
{
if (pKey != null)
{
if (f.getType().isAssignableFrom(long.class) || f.getType().isAssignableFrom(Long.class))
{
return Long.valueOf(pKey.toString());
}
else if (f.getType().isAssignableFrom(int.class) || f.getType().isAssignableFrom(Integer.class))
{
return Integer.valueOf(pKey.toString());
}
else if (f.getType().isAssignableFrom(String.class))
{
return (String) pKey;
}
else if (f.getType().isAssignableFrom(boolean.class) || f.getType().isAssignableFrom(Boolean.class))
{
return Boolean.valueOf(pKey.toString());
}
else if (f.getType().isAssignableFrom(double.class) || f.getType().isAssignableFrom(Double.class))
{
return Double.valueOf(pKey.toString());
}
else if (f.getType().isAssignableFrom(float.class) || f.getType().isAssignableFrom(Float.class))
{
return Float.valueOf(pKey.toString());
}
else
{
throw new PersistenceException("Unsupported type:" + pKey.getClass());
}
}
return null;
}
/**
* Gets the data type.
*
* @param entityMetadata
* the entity metadata
* @param arg1
* the arg1
* @return the data type
* @throws PropertyAccessException
* the property access exception
*/
private Object[] getDataType(EntityMetadata entityMetadata, Object... arg1) throws PropertyAccessException
{
Field idField = (Field) entityMetadata.getIdAttribute().getJavaMember();
PropertyAccessor> accessor = PropertyAccessorFactory.getPropertyAccessor(idField);
Object[] pKeys = new Object[arg1.length];
int cnt = 0;
for (Object r : arg1)
{
pKeys[cnt++] = accessor.fromString(idField.getClass(), r.toString());
}
return pKeys;
}
/**
* @param metadata
* @return
*/
private String getFromClause(String schemaName, String tableName)
{
String clause = tableName;
if (schemaName != null && !schemaName.isEmpty())
{
clause = schemaName + "." + tableName;
}
return clause;
}
private SessionFactory getSessionFactory()
{
return sf;
}
/**
* Updates foreign keys into master table
*
* @param metadata
* @param id
* @param relationHolders
*/
private void updateForeignKeys(EntityMetadata metadata, Object id, List relationHolders)
{
for (RelationHolder rh : relationHolders)
{
String linkName = rh.getRelationName();
Object linkValue = rh.getRelationValue();
if (linkName != null && linkValue != null)
{
String clause = getFromClause(metadata.getSchema(), metadata.getTableName());
String updateSql = "Update " + clause + " SET " + linkName + "= '" + linkValue + "' WHERE "
+ ((AbstractAttribute) metadata.getIdAttribute()).getJPAColumnName() + " = '" + id + "'";
log.warn("Executing query {}", updateSql);
s.createSQLQuery(updateSql).executeUpdate();
}
}
}
/**
* @param metadata
* @param entity
* @param relationHolders
*/
private boolean removeKunderaProxies(EntityMetadata metadata, Object entity, List relationHolders)
{
boolean proxyRemoved = false;
for (Relation relation : metadata.getRelations())
{
if (relation.isUnary())
{
Object relationObject = PropertyAccessorHelper.getObject(entity, relation.getProperty());
if (relationObject != null && ProxyHelper.isKunderaProxy(relationObject))
{
EntityMetadata relMetadata = KunderaMetadataManager.getEntityMetadata(relation.getTargetEntity());
Method idAccessorMethod = relMetadata.getReadIdentifierMethod();
Object foreignKey = null;
try
{
foreignKey = idAccessorMethod.invoke(relationObject, new Object[] {});
}
catch (IllegalArgumentException e)
{
log.error("Error while Fetching relationship value of {}", metadata.getEntityClazz(), e);
}
catch (IllegalAccessException e)
{
log.error("Error while Fetching relationship value of {}", metadata.getEntityClazz(), e);
}
catch (InvocationTargetException e)
{
log.error("Error while Fetching relationship value of {}", metadata.getEntityClazz(), e);
}
if (foreignKey != null)
{
relationObject = null;
PropertyAccessorHelper.set(entity, relation.getProperty(), relationObject);
relationHolders.add(new RelationHolder(relation.getJoinColumnName(), foreignKey));
proxyRemoved = true;
}
}
}
}
return proxyRemoved;
}
/**
* Populate enhance entities.
*
* @param m
* the m
* @param relationNames
* the relation names
* @param client
* the client
* @param sqlQuery
* the sql query
* @return the list
*/
private List populateEnhanceEntities(EntityMetadata m, List relationNames, List result)
{
List ls = null;
try
{
if (!result.isEmpty())
{
ls = new ArrayList(result.size());
for (Object o : result)
{
Class clazz = m.getEntityClazz();
Object entity = clazz.newInstance();
boolean noRelationFound = true;
if (!o.getClass().isAssignableFrom(clazz))
{
entity = ((Object[]) o)[0];
noRelationFound = false;
}
else
{
entity = o;
}
Object id = PropertyAccessorHelper.getId(entity, m);
EnhanceEntity e = new EnhanceEntity(entity, id, noRelationFound ? null : populateRelations(
relationNames, (Object[]) o));
ls.add(e);
}
}
}
catch (InstantiationException e)
{
log.error("Error during populating entities:" + e.getMessage());
throw new EntityReaderException(e);
}
catch (IllegalAccessException e)
{
log.error("Error during populating entities:" + e.getMessage());
throw new EntityReaderException(e);
}
return ls;
}
/**
* Populate relations.
*
* @param relations
* the relations
* @param o
* the o
* @return the map
*/
private Map populateRelations(List relations, Object[] o)
{
Map relationVal = new HashMap(relations.size());
int counter = 1;
for (String r : relations)
{
relationVal.put(r, o[counter++]);
}
return relationVal;
}
}