Java tutorial
/** * 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.neo4j; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import javax.persistence.GenerationType; import javax.persistence.PersistenceException; import org.apache.commons.lang.StringUtils; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.DynamicRelationshipType; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.NotInTransactionException; import org.neo4j.graphdb.Relationship; import org.neo4j.graphdb.index.Index; import org.neo4j.graphdb.index.IndexHits; import org.neo4j.graphdb.index.ReadableIndex; import org.neo4j.unsafe.batchinsert.BatchInserter; import org.neo4j.unsafe.batchinsert.BatchInserterIndexProvider; import org.neo4j.unsafe.batchinsert.BatchInserters; import org.neo4j.unsafe.batchinsert.LuceneBatchInserterIndexProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.impetus.client.neo4j.config.Neo4JPropertyReader; import com.impetus.client.neo4j.config.Neo4JPropertyReader.Neo4JSchemaMetadata; import com.impetus.client.neo4j.index.Neo4JIndexManager; import com.impetus.client.neo4j.query.Neo4JQuery; import com.impetus.kundera.PersistenceProperties; import com.impetus.kundera.client.Client; import com.impetus.kundera.client.EnhanceEntity; import com.impetus.kundera.configure.ClientProperties; import com.impetus.kundera.configure.ClientProperties.DataStore; import com.impetus.kundera.db.RelationHolder; import com.impetus.kundera.generator.Generator; import com.impetus.kundera.lifecycle.states.RemovedState; import com.impetus.kundera.metadata.KunderaMetadataManager; import com.impetus.kundera.metadata.model.EntityMetadata; import com.impetus.kundera.metadata.model.MetamodelImpl; import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; import com.impetus.kundera.metadata.model.Relation; import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; import com.impetus.kundera.persistence.EntityManagerFactoryImpl.KunderaMetadata; import com.impetus.kundera.persistence.EntityReader; import com.impetus.kundera.persistence.KunderaTransactionException; import com.impetus.kundera.persistence.TransactionBinder; import com.impetus.kundera.persistence.TransactionResource; import com.impetus.kundera.persistence.api.Batcher; import com.impetus.kundera.persistence.context.jointable.JoinTableData; import com.impetus.kundera.property.PropertyAccessorHelper; import com.impetus.kundera.utils.ReflectUtils; /** * Implementation of {@link Client} using Neo4J Native Java driver (see Embedded * Java driver at http://www.neo4j.org/develop/drivers) * * @author amresh.singh */ public class Neo4JClient extends Neo4JClientBase implements Client<Neo4JQuery>, TransactionBinder, Batcher { /** The log. */ private static Logger log = LoggerFactory.getLogger(Neo4JClient.class); /** * Reference to Neo4J client factory. */ private Neo4JClientFactory factory; /** The reader. */ private EntityReader reader; /** The mapper. */ private GraphEntityMapper mapper; /** The resource. */ private TransactionResource resource; /** The indexer. */ private Neo4JIndexManager indexer; /** * Instantiates a new neo4 j client. * * @param factory * the factory * @param puProperties * the pu properties * @param persistenceUnit * the persistence unit * @param kunderaMetadata * the kundera metadata */ Neo4JClient(final Neo4JClientFactory factory, Map<String, Object> puProperties, String persistenceUnit, final KunderaMetadata kunderaMetadata) { super(kunderaMetadata, puProperties, persistenceUnit); this.factory = factory; reader = new Neo4JEntityReader(kunderaMetadata); indexer = new Neo4JIndexManager(); mapper = new GraphEntityMapper(indexer, kunderaMetadata); populateBatchSize(persistenceUnit, puProperties); this.clientMetadata = factory.getClientMetadata(); } /* * (non-Javadoc) * * @see * com.impetus.kundera.client.ClientPropertiesSetter#populateClientProperties * (com.impetus.kundera.client.Client, java.util.Map) */ @Override public void populateClientProperties(Client client, Map<String, Object> properties) { // All client properties currently are those that are specified in // neo4j.properties (or custom XML configuration file according to // Kundera format) // No custom property currently defined by Kundera, leaving empty if (log.isDebugEnabled()) log.debug("No custom property to set for Neo4J"); for (String key : properties.keySet()) { Object value = properties.get(key); if (key.equals(PersistenceProperties.KUNDERA_BATCH_SIZE) && value instanceof Integer) { Integer batchSize = (Integer) value; ((Neo4JClient) client).setBatchSize(batchSize); } } } /** * Finds an entity from graph database. * * @param entityClass * the entity class * @param key * the key * @return the object */ @Override public Object find(Class entityClass, Object key) { GraphDatabaseService graphDb = null; if (resource != null) { graphDb = getConnection(); } if (graphDb == null) graphDb = factory.getConnection(); EntityMetadata m = KunderaMetadataManager.getEntityMetadata(kunderaMetadata, entityClass); Object entity = null; Node node = mapper.searchNode(key, m, graphDb, true); if (node != null && !((Neo4JTransaction) resource).containsNodeId(node.getId())) { entity = getEntityWithAssociationFromNode(m, node); } return entity; } /* * (non-Javadoc) * * @see com.impetus.kundera.client.Client#findAll(java.lang.Class, * java.lang.String[], java.lang.Object[]) */ @Override public <E> List<E> findAll(Class<E> entityClass, String[] columnsToSelect, Object... keys) { List entities = new ArrayList<E>(); for (Object key : keys) { entities.add(find(entityClass, key)); } return entities; } /* * (non-Javadoc) * * @see com.impetus.kundera.client.Client#find(java.lang.Class, * java.util.Map) */ @Override public <E> List<E> find(Class<E> entityClass, Map<String, String> embeddedColumnMap) { throw new UnsupportedOperationException("Embedded attributes not supported in Neo4J as of now"); } /* * (non-Javadoc) * * @see com.impetus.kundera.client.Client#close() */ @Override public void close() { // Closure is internally handled by Neo4J } /** * Deletes an entity from database. * * @param entity * the entity * @param key * the key */ @Override public void delete(Object entity, Object key) { // All Modifying Neo4J operations must be executed within a transaction checkActiveTransaction(); GraphDatabaseService graphDb = getConnection(); // Find Node for this particular entity EntityMetadata m = KunderaMetadataManager.getEntityMetadata(kunderaMetadata, entity.getClass()); Node node = mapper.searchNode(key, m, graphDb, true); if (node != null) { // Remove this particular node, if not already deleted in current // transaction if (!((Neo4JTransaction) resource).containsNodeId(node.getId())) { node.delete(); // Manually remove node index if applicable indexer.deleteNodeIndex(m, graphDb, node); // Remove all relationship edges attached to this node // (otherwise an // exception is thrown) for (Relationship relationship : node.getRelationships()) { relationship.delete(); // Manually remove relationship index if applicable indexer.deleteRelationshipIndex(m, graphDb, relationship); } ((Neo4JTransaction) resource).addNodeId(node.getId()); } } else { if (log.isDebugEnabled()) log.debug("Entity to be deleted doesn't exist in graph. Doing nothing"); } } /* * (non-Javadoc) * * @see * com.impetus.kundera.client.Client#persistJoinTable(com.impetus.kundera * .persistence.context.jointable.JoinTableData) */ @Override public void persistJoinTable(JoinTableData joinTableData) { throw new UnsupportedOperationException("Join Table not supported for Neo4J as of now"); } /* * (non-Javadoc) * * @see com.impetus.kundera.client.Client#getColumnsById(java.lang.String, * java.lang.String, java.lang.String, java.lang.String, java.lang.Object, * java.lang.Class) */ @Override public <E> List<E> getColumnsById(String schemaName, String tableName, String pKeyColumnName, String columnName, Object pKeyColumnValue, Class columnJavaType) { throw new UnsupportedOperationException("Operation not supported for Neo4J"); } /* * (non-Javadoc) * * @see com.impetus.kundera.client.Client#findIdsByColumn(java.lang.String, * 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) { throw new UnsupportedOperationException("Operation not supported for Neo4J"); } /* * (non-Javadoc) * * @see com.impetus.kundera.client.Client#deleteByColumn(java.lang.String, * java.lang.String, java.lang.String, java.lang.Object) */ @Override public void deleteByColumn(String schemaName, String tableName, String columnName, Object columnValue) { throw new UnsupportedOperationException("Operation not supported for Neo4J"); } /* * (non-Javadoc) * * @see com.impetus.kundera.client.Client#findByRelation(java.lang.String, * java.lang.Object, java.lang.Class) */ @Override public List<Object> findByRelation(String colName, Object colValue, Class entityClazz) { throw new UnsupportedOperationException("Operation not supported for Neo4J"); } /* * (non-Javadoc) * * @see com.impetus.kundera.client.Client#getReader() */ @Override public EntityReader getReader() { return reader; } /* * (non-Javadoc) * * @see com.impetus.kundera.client.Client#getQueryImplementor() */ @Override public Class<Neo4JQuery> getQueryImplementor() { return Neo4JQuery.class; } /** * Writes an entity to database. * * @param entityMetadata * the entity metadata * @param entity * the entity * @param id * the id * @param rlHolders * the rl holders */ @Override protected void onPersist(EntityMetadata entityMetadata, Object entity, Object id, List<RelationHolder> rlHolders) { if (log.isDebugEnabled()) log.debug("Persisting " + entity); // All Modifying Neo4J operations must be executed within a transaction checkActiveTransaction(); GraphDatabaseService graphDb = getConnection(); try { // Top level node Node node = mapper.getNodeFromEntity(entity, id, graphDb, entityMetadata, isUpdate); if (node != null) { MetamodelImpl metamodel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata() .getMetamodel(getPersistenceUnit()); ((Neo4JTransaction) resource).addProcessedNode(id, node); if (!rlHolders.isEmpty()) { for (RelationHolder rh : rlHolders) { // Search Node (to be connected to ) in Neo4J graph EntityMetadata targetNodeMetadata = KunderaMetadataManager .getEntityMetadata(kunderaMetadata, rh.getRelationValue().getClass()); Object targetNodeKey = PropertyAccessorHelper.getId(rh.getRelationValue(), targetNodeMetadata); // Node targetNode = mapper.searchNode(targetNodeKey, // targetNodeMetadata, graphDb); Node targetNode = null; // Target node connected through // relationship /** * If Relationship is with an entity in Neo4J, Target * node must already have been created Get a handle of * it from processed nodes and add edges to it. Else, if * relationship is with an entity in a database other * than Neo4J, create a "Proxy Node" that points to a * row in other database. This proxy node contains key * equal to primary key of row in other database. * */ if (isEntityForNeo4J(targetNodeMetadata)) { targetNode = ((Neo4JTransaction) resource).getProcessedNode(targetNodeKey); } else { // Create Proxy nodes for insert requests if (!isUpdate) { targetNode = mapper.createProxyNode(id, targetNodeKey, graphDb, entityMetadata, targetNodeMetadata); } } if (targetNode != null) { // Join this node (source node) to target node via // relationship DynamicRelationshipType relType = DynamicRelationshipType .withName(rh.getRelationName()); Relationship relationship = node.createRelationshipTo(targetNode, relType); // Populate relationship's own properties into it Object relationshipObj = rh.getRelationVia(); if (relationshipObj != null) { mapper.populateRelationshipProperties(entityMetadata, targetNodeMetadata, relationship, relationshipObj); // After relationship creation, manually index // it if desired EntityMetadata relationMetadata = KunderaMetadataManager .getEntityMetadata(kunderaMetadata, relationshipObj.getClass()); if (!isUpdate) { indexer.indexRelationship(relationMetadata, graphDb, relationship, metamodel); } else { indexer.updateRelationshipIndex(relationMetadata, graphDb, relationship, metamodel); } } } } } // After node creation, manually index this node, if desired if (!isUpdate) { indexer.indexNode(entityMetadata, graphDb, node, metamodel); } else { indexer.updateNodeIndex(entityMetadata, graphDb, node, metamodel); } } } catch (Exception e) { log.error("Error while persisting entity " + entity + ", Caused by: ", e); throw new PersistenceException(e); } } /* * (non-Javadoc) * * @see * com.impetus.kundera.persistence.api.Batcher#addBatch(com.impetus.kundera * .graph.Node) */ @Override public void addBatch(com.impetus.kundera.graph.Node node) { if (node != null) { nodes.add(node); } if (batchSize > 0 && batchSize == nodes.size()) { executeBatch(); nodes.clear(); } } /* * (non-Javadoc) * * @see com.impetus.kundera.persistence.api.Batcher#executeBatch() */ @Override public int executeBatch() { if (batchSize > 0) { boolean nodeAutoIndexingEnabled = indexer.isNodeAutoIndexingEnabled(factory.getConnection()); boolean relationshipAutoIndexingEnabled = indexer .isRelationshipAutoIndexingEnabled(factory.getConnection()); BatchInserter inserter = getBatchInserter(); BatchInserterIndexProvider indexProvider = new LuceneBatchInserterIndexProvider(inserter); if (inserter == null) { log.error("Unable to create instance of BatchInserter. Opertion will fail"); throw new PersistenceException("Unable to create instance of BatchInserter. Opertion will fail"); } if (resource != null && resource.isActive()) { log.error("Batch Insertion MUST not be executed in a transaction"); throw new PersistenceException("Batch Insertion MUST not be executed in a transaction"); } Map<Object, Long> pkToNodeIdMap = new HashMap<Object, Long>(); for (com.impetus.kundera.graph.Node graphNode : nodes) { if (graphNode.isDirty()) { graphNode.handlePreEvent(); // Delete can not be executed in batch, deleting normally if (graphNode.isInState(RemovedState.class)) { delete(graphNode.getData(), graphNode.getEntityId()); } else if (graphNode.isUpdate()) { // Neo4J allows only batch insertion, follow usual path // for normal updates persist(graphNode); } else { // Insert node Object entity = graphNode.getData(); EntityMetadata m = KunderaMetadataManager.getEntityMetadata(kunderaMetadata, entity.getClass()); Object pk = PropertyAccessorHelper.getId(entity, m); Map<String, Object> nodeProperties = mapper.createNodeProperties(entity, m); long nodeId = inserter.createNode(nodeProperties); pkToNodeIdMap.put(pk, nodeId); // Index Node indexer.indexNodeUsingBatchIndexer(indexProvider, m, nodeId, nodeProperties, nodeAutoIndexingEnabled); // Insert relationships for this particular node if (!getRelationHolders(graphNode).isEmpty()) { for (RelationHolder rh : getRelationHolders(graphNode)) { // Search Node (to be connected to ) in Neo4J // graph EntityMetadata targetNodeMetadata = KunderaMetadataManager .getEntityMetadata(kunderaMetadata, rh.getRelationValue().getClass()); Object targetNodeKey = PropertyAccessorHelper.getId(rh.getRelationValue(), targetNodeMetadata); Long targetNodeId = pkToNodeIdMap.get(targetNodeKey); if (targetNodeId != null) { /** * Join this node (source node) to target * node via relationship */ // Relationship Type DynamicRelationshipType relType = DynamicRelationshipType .withName(rh.getRelationName()); // Relationship Properties Map<String, Object> relationshipProperties = null; Object relationshipObj = rh.getRelationVia(); if (relationshipObj != null) { EntityMetadata relationMetadata = KunderaMetadataManager .getEntityMetadata(kunderaMetadata, relationshipObj.getClass()); relationshipProperties = mapper.createRelationshipProperties(m, targetNodeMetadata, relationshipObj); // Finally insert relationship long relationshipId = inserter.createRelationship(nodeId, targetNodeId, relType, relationshipProperties); // Index this relationship indexer.indexRelationshipUsingBatchIndexer(indexProvider, relationMetadata, relationshipId, relationshipProperties, relationshipAutoIndexingEnabled); } } } } } graphNode.handlePostEvent(); } } // Shutdown Batch inserter indexProvider.shutdown(); inserter.shutdown(); // Restore Graph Database service factory.setConnection((GraphDatabaseService) factory.createPoolOrConnection()); return pkToNodeIdMap.size(); } else { return 0; } } /** * Populates relationship entities into original entity. * * @param m * the m * @param entity * the entity * @param relationMap * the relation map * @param node * the node * @param nodeIdToEntityMap * the node id to entity map */ private void populateRelations(EntityMetadata m, Object entity, Map<String, Object> relationMap, Node node, Map<Long, Object> nodeIdToEntityMap) { // Populate all relationship entities that are in Neo4J for (Relation relation : m.getRelations()) { if (relation != null) { Class<?> targetEntityClass = relation.getTargetEntity(); EntityMetadata targetEntityMetadata = KunderaMetadataManager.getEntityMetadata(kunderaMetadata, targetEntityClass); Field property = relation.getProperty(); if (relation.getPropertyType().isAssignableFrom(Map.class)) { Map<Object, Object> targetEntitiesMap = new HashMap<Object, Object>(); // If relationship entity is stored into Neo4J, fetch it // immediately if (isEntityForNeo4J(targetEntityMetadata)) { for (Relationship relationship : node.getRelationships(Direction.OUTGOING, DynamicRelationshipType.withName(relation.getJoinColumnName(kunderaMetadata)))) { if (relationship == null) { continue; } // Target Entity Node endNode = relationship.getEndNode(); if (endNode == null) { continue; } Object targetEntity = nodeIdToEntityMap.get(endNode.getId()); if (targetEntity == null) { targetEntity = mapper.getEntityFromNode(endNode, targetEntityMetadata); } // Relationship Entity Object relationshipEntity = mapper.getEntityFromRelationship(relationship, m, relation); // If this relationship is bidirectional, put source // entity into Map field for target entity Field bidirectionalField = relation.getBiDirectionalField(); Map<Object, Object> sourceEntitiesMap = new HashMap<Object, Object>(); if (bidirectionalField != null) { for (Relationship incomingRelationship : endNode .getRelationships(Direction.INCOMING, DynamicRelationshipType .withName(relation.getJoinColumnName(kunderaMetadata)))) { Node startNode = incomingRelationship.getStartNode(); Object sourceEntity = nodeIdToEntityMap.get(startNode.getId()); if (sourceEntity == null) { sourceEntity = mapper.getEntityFromNode(startNode, m); nodeIdToEntityMap.put(startNode.getId(), sourceEntity); } sourceEntitiesMap.put(relationshipEntity, sourceEntity); } PropertyAccessorHelper.set(targetEntity, bidirectionalField, sourceEntitiesMap); } // Set references to Target and owning entity in // relationship entity Class<?> relationshipClass = relation.getMapKeyJoinClass(); for (Field f : relationshipClass.getDeclaredFields()) { if (!ReflectUtils.isTransientOrStatic(f)) { if (f.getType().equals(m.getEntityClazz())) { PropertyAccessorHelper.set(relationshipEntity, f, entity); } else if (f.getType().equals(targetEntityClass)) { PropertyAccessorHelper.set(relationshipEntity, f, targetEntity); } } } targetEntitiesMap.put(relationshipEntity, targetEntity); } PropertyAccessorHelper.set(entity, property, targetEntitiesMap); } /** * If relationship entity is stored in a database other than * Neo4J foreign keys are stored in "Proxy Nodes", retrieve * these foreign keys and set into EnhanceEntity */ else { for (Relationship relationship : node.getRelationships(Direction.OUTGOING, DynamicRelationshipType.withName(relation.getJoinColumnName(kunderaMetadata)))) { Node proxyNode = relationship.getEndNode(); String targetEntityIdColumnName = ((AbstractAttribute) targetEntityMetadata .getIdAttribute()).getJPAColumnName(); Object targetObjectId = proxyNode.getProperty(targetEntityIdColumnName); Object relationshipEntity = mapper.getEntityFromRelationship(relationship, m, relation); targetEntitiesMap.put(targetObjectId, relationshipEntity); } relationMap.put(relation.getJoinColumnName(kunderaMetadata), targetEntitiesMap); } } } } } /** * Returns instance of {@link BatchInserter}. * * @return the batch inserter */ protected BatchInserter getBatchInserter() { PersistenceUnitMetadata puMetadata = kunderaMetadata.getApplicationMetadata() .getPersistenceUnitMetadata(getPersistenceUnit()); Properties props = puMetadata.getProperties(); // Datastore file path String datastoreFilePath = (String) props.get(PersistenceProperties.KUNDERA_DATASTORE_FILE_PATH); if (StringUtils.isEmpty(datastoreFilePath)) { throw new PersistenceException( "For Neo4J, it's mandatory to specify kundera.datastore.file.path property in persistence.xml"); } // Shut down Graph DB, at a time only one service may have lock on DB // file if (factory.getConnection() != null) { factory.getConnection().shutdown(); } BatchInserter inserter = null; // Create Batch inserter with configuration if specified Neo4JSchemaMetadata nsmd = Neo4JPropertyReader.nsmd; ClientProperties cp = nsmd != null ? nsmd.getClientProperties() : null; if (cp != null) { DataStore dataStore = nsmd != null ? nsmd.getDataStore() : null; Properties properties = dataStore != null && dataStore.getConnection() != null ? dataStore.getConnection().getProperties() : null; if (properties != null) { Map<String, String> config = new HashMap<String, String>((Map) properties); inserter = BatchInserters.inserter(datastoreFilePath, config); } } // Create Batch inserter without configuration if not provided if (inserter == null) { inserter = BatchInserters.inserter(datastoreFilePath); } return inserter; } /** * Binds Transaction resource to this client. * * @param resource * the resource */ @Override public void bind(TransactionResource resource) { if (resource != null && resource instanceof Neo4JTransaction) { ((Neo4JTransaction) resource).setGraphDb(factory.getConnection()); this.resource = resource; } else { throw new KunderaTransactionException("Invalid transaction resource provided:" + resource + " Should have been an instance of :" + Neo4JTransaction.class); } } /** * Execute lucene query. * * @param m * the m * @param luceneQuery * the lucene query * @return the list */ public List<Object> executeLuceneQuery(EntityMetadata m, String luceneQuery) { log.info("Executing Lucene Query on Neo4J:" + luceneQuery); GraphDatabaseService graphDb = getConnection(); List<Object> entities = new ArrayList<Object>(); if (!indexer.isNodeAutoIndexingEnabled(graphDb) && m.isIndexable()) { Index<Node> nodeIndex = graphDb.index().forNodes(m.getIndexName()); IndexHits<Node> hits = nodeIndex.query(luceneQuery); addEntityFromIndexHits(m, entities, hits); } else { ReadableIndex<Node> autoNodeIndex = graphDb.index().getNodeAutoIndexer().getAutoIndex(); IndexHits<Node> hits = autoNodeIndex.query(luceneQuery); addEntityFromIndexHits(m, entities, hits); } return entities; } /** * Adds the entity from index hits. * * @param m * the m * @param entities * the entities * @param hits * the hits */ protected void addEntityFromIndexHits(EntityMetadata m, List<Object> entities, IndexHits<Node> hits) { for (Node node : hits) { if (node != null) { Object entity = getEntityWithAssociationFromNode(m, node); if (entity != null) { entities.add(entity); } } } } /** * Gets the entity with association from node. * * @param m * the m * @param node * the node * @return the entity with association from node */ private Object getEntityWithAssociationFromNode(EntityMetadata m, Node node) { Map<String, Object> relationMap = new HashMap<String, Object>(); /** * Map containing Node ID as key and Entity object as value. Helps cache * entity objects found earlier for faster lookup and prevents repeated * processing */ Map<Long, Object> nodeIdToEntityMap = new HashMap<Long, Object>(); Object entity = mapper.getEntityFromNode(node, m); nodeIdToEntityMap.put(node.getId(), entity); populateRelations(m, entity, relationMap, node, nodeIdToEntityMap); nodeIdToEntityMap.clear(); if (!relationMap.isEmpty() && entity != null) { return new EnhanceEntity(entity, PropertyAccessorHelper.getId(entity, m), relationMap); } else { return entity; } } /** * Checks whether there is an active transaction within this client Batch * operations are run without any transaction boundary hence this check is * not applicable for them All Modifying Neo4J operations must be executed * within a transaction. */ private void checkActiveTransaction() { if (batchSize == 0 && (resource == null || !resource.isActive())) { throw new NotInTransactionException( "All Modifying Neo4J operations must be executed within a transaction"); } } /** * Gets the connection. * * @return the connection */ public GraphDatabaseService getConnection() { if (resource != null) { return ((Neo4JTransaction) resource).getGraphDb(); } else { return factory.getConnection(); } } /* * (non-Javadoc) * * @see com.impetus.kundera.client.Client#getIdGenerator() */ @Override public Generator getIdGenerator() { throw new UnsupportedOperationException( GenerationType.class.getSimpleName() + " Strategies not supported by this client : Neo4JClient"); } }