@Override protected void deleteEntity(PersistentEntity pe, Object obj) { EntityAccess entityAccess = createEntityAccess(pe, obj); if (cancelDelete(pe, entityAccess)) { return; } for (Association association : pe.getAssociations()) { if (association.isOwningSide() && association.doesCascade(CascadeType.REMOVE)) { log.debug("cascading delete for property " + association.getName()); GraphPersistentEntity otherPersistentEntity = (GraphPersistentEntity) association.getAssociatedEntity(); Object otherSideValue = entityAccess.getProperty(association.getName()); if (association instanceof ToOne) { deleteEntity(otherPersistentEntity, otherSideValue); } else { deleteEntities(otherPersistentEntity, (Iterable) otherSideValue); } } } getCypherEngine() .execute( String.format( "MATCH (n:%s) WHERE n.__id__={id} OPTIONAL MATCH (n)-[r]-() DELETE r,n", ((GraphPersistentEntity) pe).getLabel()), Collections.singletonMap("id", entityAccess.getIdentifier())); firePostDeleteEvent(pe, entityAccess); }
private Object unmarshall(PersistentEntity persistentEntity, Long id, Map<String, Object> data) { log.debug("unmarshalling entity {}, props {}, {}", id, data); EntityAccess entityAccess = new EntityAccess(persistentEntity, persistentEntity.newInstance()); entityAccess.setConversionService(persistentEntity.getMappingContext().getConversionService()); entityAccess.setIdentifier(id); data.remove("__id__"); for (PersistentProperty property : entityAccess.getPersistentEntity().getPersistentProperties()) { String propertyName = property.getName(); if (property instanceof Simple) { // implicitly sets version property as well entityAccess.setProperty(propertyName, data.remove(propertyName)); // } else if (property instanceof OneToOne) { // log.error("property " + property.getName() + " is of type " + // property.getClass().getSuperclass()); } else if (property instanceof ToOne) { ToOne to = (ToOne) property; CypherResult cypherResult = getSession() .getNativeInterface() .execute( CypherBuilder.findRelationshipEndpointIdsFor(to), Collections.singletonMap("id", id)); Map<String, Object> row = IteratorUtil.singleOrNull(cypherResult); if (row != null) { Long endpointId = (Long) row.get("id"); entityAccess.setProperty( propertyName, getMappingContext() .getProxyFactory() .createProxy(session, to.getAssociatedEntity().getJavaClass(), endpointId)); } } else if ((property instanceof OneToMany) || (property instanceof ManyToMany)) { LazyEnititySet lazyEnititySet = new LazyEnititySet( entityAccess, (Association) property, getMappingContext().getProxyFactory(), getSession()); entityAccess.setProperty(propertyName, lazyEnititySet); } else { throw new IllegalArgumentException( "property $property.name is of type ${property.class.superclass}"); } } if (!data.isEmpty()) { GroovyObject go = (GroovyObject) (entityAccess.getEntity()); go.setProperty(Neo4jGormEnhancer.UNDECLARED_PROPERTIES, data); } firePostLoadEvent(entityAccess.getPersistentEntity(), entityAccess); return entityAccess.getEntity(); }
@Override protected void deleteEntities( PersistentEntity pe, @SuppressWarnings("rawtypes") Iterable objects) { List<EntityAccess> entityAccesses = new ArrayList<EntityAccess>(); List<Object> ids = new ArrayList<Object>(); Map<PersistentEntity, Collection<Object>> cascades = new HashMap<PersistentEntity, Collection<Object>>(); for (Object obj : objects) { EntityAccess entityAccess = createEntityAccess(pe, obj); if (cancelDelete(pe, entityAccess)) { return; } entityAccesses.add(entityAccess); ids.add(entityAccess.getIdentifier()); // populate cascades for (Association association : pe.getAssociations()) { Object property = entityAccess.getProperty(association.getName()); if (association.isOwningSide() && association.doesCascade(CascadeType.REMOVE) && (property != null)) { PersistentEntity associatedEntity = association.getAssociatedEntity(); Collection<Object> cascadesForPersistentEntity = cascades.get(associatedEntity); if (cascadesForPersistentEntity == null) { cascadesForPersistentEntity = new ArrayList<Object>(); cascades.put(associatedEntity, cascadesForPersistentEntity); } if (association instanceof ToOne) { cascadesForPersistentEntity.add(property); } else { cascadesForPersistentEntity.addAll((Collection<?>) property); } } } } for (Map.Entry<PersistentEntity, Collection<Object>> entry : cascades.entrySet()) { deleteEntities(entry.getKey(), entry.getValue()); } getCypherEngine() .execute( String.format( "MATCH (n:%s) WHERE n.__id__ in {ids} OPTIONAL MATCH (n)-[r]-() DELETE r,n", ((GraphPersistentEntity) pe).getLabel()), Collections.singletonMap("ids", ids)); for (EntityAccess entityAccess : entityAccesses) { firePostDeleteEvent(pe, entityAccess); } }