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 DBObject createNewEntry(String family) { BasicDBObject dbo = new BasicDBObject(); PersistentEntity persistentEntity = getPersistentEntity(); if (!persistentEntity.isRoot()) { dbo.put(MONGO_CLASS_FIELD, persistentEntity.getDiscriminator()); } return dbo; }
public PersistentEntity getRootEntity() { if (isRoot() || getParentEntity() == null) { return this; } PersistentEntity parent = getParentEntity(); while (!parent.isRoot()) { parent = parent.getParentEntity(); } return parent; }
private String getCollectionName(PersistentEntity persistentEntity, DBObject nativeEntry) { String collectionName; if (persistentEntity.isRoot()) { MongoSession mongoSession = (MongoSession) getSession(); collectionName = mongoSession.getCollectionName(persistentEntity); } else { MongoSession mongoSession = (MongoSession) getSession(); collectionName = mongoSession.getCollectionName(persistentEntity.getRootEntity()); } return collectionName; }
/** * Get hold of the GrailsDomainClassProperty represented by the targetClass' propertyName, * assuming targetClass corresponds to a GrailsDomainClass. */ private static PersistentProperty getGrailsDomainClassProperty( AbstractHibernateDatastore datastore, Class<?> targetClass, String propertyName) { PersistentEntity grailsClass = datastore != null ? datastore.getMappingContext().getPersistentEntity(targetClass.getName()) : null; if (grailsClass == null) { throw new IllegalArgumentException( "Unexpected: class is not a domain class:" + targetClass.getName()); } return grailsClass.getPropertyByName(propertyName); }
@Override public Serializable getObjectIdentifier(Object instance) { if (instance == null) return null; if (proxyHandler.isProxy(instance)) { return ((HibernateProxy) instance).getHibernateLazyInitializer().getIdentifier(); } Class<?> type = instance.getClass(); ClassPropertyFetcher cpf = ClassPropertyFetcher.forClass(type); final PersistentEntity persistentEntity = getMappingContext().getPersistentEntity(type.getName()); if (persistentEntity != null) { return (Serializable) cpf.getPropertyValue(instance, persistentEntity.getIdentity().getName()); } return null; }
@Override @SuppressWarnings({"rawtypes", "unchecked"}) public Family createMappedForm(PersistentEntity entity) { ClassPropertyFetcher cpf = ClassPropertyFetcher.forClass(entity.getJavaClass()); final Closure value = cpf.getStaticPropertyValue(GormProperties.MAPPING, Closure.class); if (value == null) { return new Region(); } final Region family = new Region(); AttributesFactory factory = new AttributesFactory() { @SuppressWarnings("unused") public void setRegion(String name) { family.setRegion(name); } }; factory.setDataPolicy(defaultDataPolicy); MappingConfigurationBuilder builder = new MappingConfigurationBuilder(factory, KeyValue.class); builder.evaluate(value); entityToPropertyMap.put(entity, builder.getProperties()); final RegionAttributes regionAttributes = factory.create(); family.setRegionAttributes(regionAttributes); family.setCacheListeners(regionAttributes.getCacheListeners()); family.setDataPolicy(regionAttributes.getDataPolicy()); family.setCacheLoader(regionAttributes.getCacheLoader()); family.setCacheWriter(regionAttributes.getCacheWriter()); builder = new MappingConfigurationBuilder(family, KeyValue.class); builder.evaluate(value); return family; }
@Override public Object invokeMethod(String name, Object obj) { Object[] args = obj.getClass().isArray() ? (Object[]) obj : new Object[] {obj}; if (isCriteriaConstructionMethod(name, args)) { initializeQuery(); uniqueResult = false; invokeClosureNode(args[0]); Object result; if (!uniqueResult) { result = query.list(); } else { result = query.singleResult(); } query = null; return result; } MetaMethod metaMethod = getMetaClass().getMetaMethod(name, args); if (metaMethod != null) { return metaMethod.invoke(this, args); } metaMethod = queryMetaClass.getMetaMethod(name, args); if (metaMethod != null) { return metaMethod.invoke(query, args); } if (args.length == 1 && args[0] instanceof Closure) { final PersistentProperty property = persistentEntity.getPropertyByName(name); if (property instanceof Association) { Association association = (Association) property; Query previousQuery = query; PersistentEntity previousEntity = persistentEntity; Query associationQuery = null; try { associationQuery = query.createQuery(property.getName()); if (associationQuery instanceof AssociationQuery) { previousQuery.add((Query.Criterion) associationQuery); } query = associationQuery; persistentEntity = association.getAssociatedEntity(); invokeClosureNode(args[0]); return query; } finally { persistentEntity = previousEntity; query = previousQuery; } } } throw new MissingMethodException(name, getClass(), args); }
/** * Returns mapped domain name (*unprefixed*) for the specified @{link PersistentEntity}. * * @param entity * @return */ public static String getMappedDomainName(PersistentEntity entity) { @SuppressWarnings("unchecked") ClassMapping<SimpleDBDomainClassMappedForm> classMapping = entity.getMapping(); SimpleDBDomainClassMappedForm mappedForm = classMapping.getMappedForm(); String entityFamily = getFamily(entity, mappedForm); return entityFamily; }
@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); }
int calcInheritenceChain(PersistentEntity pe) { if (pe == null) { return 0; } else { return calcInheritenceChain(pe.getParentEntity()) + 1; } }
public static List<String> getDatasourceNames(PersistentEntity domainClass) { final Entity mappedForm = domainClass.getMapping().getMappedForm(); if (mappedForm instanceof Mapping) { Mapping mapping = (Mapping) mappedForm; return mapping.getDatasources(); } return Collections.singletonList(Mapping.DEFAULT_DATA_SOURCE); }
@Override protected List<Object> retrieveAllEntities( PersistentEntity persistentEntity, Iterable<Serializable> keys) { Query query = session.createQuery(persistentEntity.getJavaClass()); PersistentProperty identity = persistentEntity.getIdentity(); if (keys instanceof List) { List actualKeys = new ArrayList(); Iterator iterator = keys.iterator(); while (iterator.hasNext()) { Object key = iterator.next(); Object id = getIdentifierForKey(key); actualKeys.add(id); } query.in(identity.getName(), actualKeys); } else { List<Serializable> keyList = new ArrayList<Serializable>(); for (Serializable key : keys) { keyList.add(key); } query.in(identity.getName(), keyList); } List<Object> entityResults = new ArrayList<Object>(); Iterator<Serializable> keyIterator = keys.iterator(); Map<Serializable, Object> resultMap = new HashMap<Serializable, Object>(); for (Object o : query.list()) { if (o instanceof DBObject) { DBObject dbo = (DBObject) o; o = createObjectFromNativeEntry( getPersistentEntity(), (Serializable) dbo.get(MONGO_ID_FIELD), dbo); } resultMap.put(getObjectIdentifier(o), o); } while (keyIterator.hasNext()) { Object key = getIdentifierForKey(keyIterator.next()); ConversionService conversionService = getMappingContext().getConversionService(); key = conversionService.convert(key, identity.getType()); Object o = resultMap.get(key); entityResults.add(o); // may add null, so entityResults list size matches input list size. } return entityResults; }
private static String getFamily( PersistentEntity persistentEntity, SimpleDBDomainClassMappedForm mappedForm) { String table = null; if (mappedForm != null) { table = mappedForm.getFamily(); } if (table == null) table = persistentEntity.getJavaClass().getSimpleName(); return table; }
@SuppressWarnings("unchecked") @Override public Table createMappedForm(PersistentEntity entity) { Table table = super.createMappedForm(entity); CassandraPersistentEntity cassandraPersistentEntity = (CassandraPersistentEntity) entity; // read tableOptions ClassPropertyFetcher cpf = ClassPropertyFetcher.forClass(entity.getJavaClass()); final Closure value = cpf.getStaticPropertyValue(TABLE_PROPERTIES, Closure.class); if (value != null) { MapConfigurationBuilder builder = new MapConfigurationBuilder(); try { builder.evaluate(value); } catch (Exception e) { throw new IllegalMappingException( String.format("Error reading %s : %s", TABLE_PROPERTIES, e.toString())); } table.setTableProperties(builder.getProperties()); } if (table.getKeyspace() == null) { table.setKeyspace(keyspace); } // additional static mapping block handling Map<String, Column> properties = entityToPropertyMap.get(entity); Object version = properties.get(MappingConfigurationBuilder.VERSION_KEY); if (version instanceof Boolean) { cassandraPersistentEntity.setVersion((Boolean) version); } Column idProperty = properties.get(IDENTITY_PROPERTY); Iterator<Entry<String, Column>> propertyIterator = properties.entrySet().iterator(); while (propertyIterator.hasNext()) { Entry<String, Column> entry = propertyIterator.next(); if (entry.getValue() instanceof Column) { String name = entry.getKey(); Column column = entry.getValue(); if (idProperty != null && idProperty.getName() != null && idProperty.getName().equals(name)) { // remove extra column created if id property in constraints block, as it conflicts with // the column created in mapping block. // constraints will be handled elsewhere in GORM propertyIterator.remove(); continue; } if (column.getName() == null) { column.setName(name); } table.addColumn(column); } } return table; }
protected void validatePropertyName(String propertyName, String methodName) { if (propertyName == null) { throw new IllegalArgumentException( "Cannot use [" + methodName + "] restriction with null property name"); } PersistentProperty property = persistentEntity.getPropertyByName(propertyName); if (property == null && persistentEntity.getIdentity().getName().equals(propertyName)) { property = persistentEntity.getIdentity(); } if (property == null) { throw new IllegalArgumentException( "Property [" + propertyName + "] is not a valid property of class [" + persistentEntity + "]"); } }
public static org.hibernate.criterion.DetachedCriteria getHibernateDetachedCriteria( AbstractHibernateQuery hibernateQuery, QueryableCriteria<?> queryableCriteria) { String alias = queryableCriteria.getAlias(); PersistentEntity persistentEntity = queryableCriteria.getPersistentEntity(); Class targetClass = persistentEntity.getJavaClass(); org.hibernate.criterion.DetachedCriteria detachedCriteria; if (alias != null) { detachedCriteria = org.hibernate.criterion.DetachedCriteria.forClass(targetClass, alias); } else { detachedCriteria = org.hibernate.criterion.DetachedCriteria.forClass(targetClass); } populateHibernateDetachedCriteria( new HibernateQuery(detachedCriteria, persistentEntity), detachedCriteria, queryableCriteria); return detachedCriteria; }
@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); } }
@Override protected PersistentEntity discriminatePersistentEntity( PersistentEntity persistentEntity, DBObject nativeEntry) { final Object o = nativeEntry.get(MONGO_CLASS_FIELD); if (o != null) { final String className = o.toString(); final PersistentEntity childEntity = getMappingContext() .getChildEntityByDiscriminator(persistentEntity.getRootEntity(), className); if (childEntity != null) { return childEntity; } } return super.discriminatePersistentEntity(persistentEntity, nativeEntry); }
@Override @SuppressWarnings("unchecked") public Identity<Column> createIdentity( PersistentEntity owner, MappingContext context, PropertyDescriptor pd) { final Table table = (Table) owner.getMapping().getMappedForm(); if (table.hasCompositePrimaryKeys()) { return new Identity<Column>(owner, context, table.getPrimaryKeyNames()[0], Map.class) { PropertyMapping<Column> propertyMapping = createPropertyMapping(this, owner); public PropertyMapping<Column> getMapping() { return propertyMapping; } }; } return super.createIdentity(owner, context, pd); }
public MongoEntityPersister( MappingContext mappingContext, PersistentEntity entity, MongoSession mongoSession, ApplicationEventPublisher publisher) { super(mappingContext, entity, mongoSession, publisher); MongoDatastore datastore = (MongoDatastore) mongoSession.getDatastore(); mongoTemplate = datastore.getMongoTemplate(entity); collectionName = datastore.getCollectionName(entity); if (!(entity instanceof EmbeddedPersistentEntity)) { PersistentProperty identity = entity.getIdentity(); if (identity != null) { hasNumericalIdentifier = Long.class.isAssignableFrom(identity.getType()); hasStringIdentifier = String.class.isAssignableFrom(identity.getType()); } } }
@Override protected MappingConfigurationBuilder createConfigurationBuilder( PersistentEntity entity, Mapping mapping) { return new HibernateMappingBuilder(mapping, entity.getName(), defaultConstraints); }
public boolean isOwningEntity(PersistentEntity owner) { return domainClass.isOwningClass(owner.getJavaClass()); }
/** * @see #getPersistentProperties(Class, org.grails.datastore.mapping.model.MappingContext, * org.grails.datastore.mapping.model.ClassMapping) */ public List<PersistentProperty> getPersistentProperties( PersistentEntity entity, MappingContext context, ClassMapping classMapping) { return getPersistentProperties(entity.getJavaClass(), context, classMapping); }
@Override public CassandraPersistentProperty createPersistentProperty( Field field, PropertyDescriptor descriptor, CassandraPersistentEntity<?> owner, SimpleTypeHolder simpleTypeHolder) { PersistentEntity gormEntity = gormCassandraMappingContext.getPersistentEntity(owner.getName()); final CassandraPersistentProperty property = super.createPersistentProperty(field, descriptor, owner, simpleTypeHolder); final CassandraPersistentProperty transientProperty = new BasicCassandraPersistentProperty( field, descriptor, owner, (CassandraSimpleTypeHolder) simpleTypeHolder) { public boolean isTransient() { return true; } }; if (field == null && !property.usePropertyAccess()) { return transientProperty; } if (field != null && Modifier.isTransient(field.getModifiers())) { return transientProperty; } if (field != null && grails.core.GrailsDomainClassProperty.ERRORS.equals(field.getName())) { return transientProperty; } if (field != null && field.getType().equals(Errors.class)) { return transientProperty; } if (field != null && (field.getName().contains(INTERNAL_MARKER) || field.getName().startsWith(INTERNAL_GRAILS_FIELD_MARKER))) { return transientProperty; } if (descriptor != null && descriptor.getWriteMethod() == null && descriptor.getReadMethod() == null) { return transientProperty; } Class<?> rawType = field != null ? field.getType() : descriptor != null ? descriptor.getPropertyType() : null; if (rawType == null) { return transientProperty; } if (rawType.isEnum()) { // persist as a string return new BasicCassandraPersistentProperty( field, descriptor, owner, (CassandraSimpleTypeHolder) simpleTypeHolder) { public com.datastax.driver.core.DataType getDataType() { return CassandraSimpleTypeHolder.getDataTypeFor(String.class); }; public java.lang.Class<?> getType() { return String.class; }; public boolean usePropertyAccess() { return true; }; }; } else if (URL.class.isAssignableFrom(rawType) || TimeZone.class.isAssignableFrom(rawType) || Locale.class.isAssignableFrom(rawType) || Currency.class.isAssignableFrom(rawType) || Calendar.class.isAssignableFrom(rawType)) { // persist as a string return new BasicCassandraPersistentProperty( field, descriptor, owner, (CassandraSimpleTypeHolder) simpleTypeHolder) { public com.datastax.driver.core.DataType getDataType() { return CassandraSimpleTypeHolder.getDataTypeFor(String.class); }; public java.lang.Class<?> getType() { return String.class; }; public boolean isEntity() { return false; }; public boolean usePropertyAccess() { return true; }; }; } else if (field != null && GrailsDomainClassProperty.VERSION.equals(field.getName()) && !gormEntity.isVersioned()) { return transientProperty; } // for collections or maps of non-primitive types, i.e associations, // return transient property as spring data cassandra doesn't support if (!property.isTransient()) { if (property.isMap() || property.isCollectionLike()) { try { property.getDataType(); } catch (InvalidDataAccessApiUsageException e) { return transientProperty; } } } return property; }
private void persistAssociationsOfEntity( PersistentEntity pe, EntityAccess entityAccess, boolean isUpdate) { Object obj = entityAccess.getEntity(); DirtyCheckable dirtyCheckable = null; if (obj instanceof DirtyCheckable) { dirtyCheckable = (DirtyCheckable) obj; } for (PersistentProperty pp : pe.getAssociations()) { if ((!isUpdate) || ((dirtyCheckable != null) && dirtyCheckable.hasChanged(pp.getName()))) { Object propertyValue = entityAccess.getProperty(pp.getName()); if ((pp instanceof OneToMany) || (pp instanceof ManyToMany)) { Association association = (Association) pp; if (propertyValue != null) { if (association.isBidirectional()) { // Populate other side of bidi for (Object associatedObject : (Iterable) propertyValue) { EntityAccess assocEntityAccess = createEntityAccess(association.getAssociatedEntity(), associatedObject); assocEntityAccess.setProperty(association.getReferencedPropertyName(), obj); } } Iterable targets = (Iterable) propertyValue; persistEntities(association.getAssociatedEntity(), targets); boolean reversed = RelationshipUtils.useReversedMappingFor(association); if (!reversed) { if (!(propertyValue instanceof LazyEnititySet)) { LazyEnititySet les = new LazyEnititySet( entityAccess, association, getMappingContext().getProxyFactory(), getSession()); les.addAll(targets); entityAccess.setProperty(association.getName(), les); } } } } else if (pp instanceof ToOne) { if (propertyValue != null) { ToOne to = (ToOne) pp; if (to.isBidirectional()) { // Populate other side of bidi EntityAccess assocEntityAccess = createEntityAccess(to.getAssociatedEntity(), propertyValue); if (to instanceof OneToOne) { assocEntityAccess.setProperty(to.getReferencedPropertyName(), obj); } else { Collection collection = (Collection) assocEntityAccess.getProperty(to.getReferencedPropertyName()); if (collection == null) { collection = new ArrayList(); assocEntityAccess.setProperty(to.getReferencedPropertyName(), collection); } if (!collection.contains(obj)) { collection.add(obj); } } } persistEntity(to.getAssociatedEntity(), propertyValue); boolean reversed = RelationshipUtils.useReversedMappingFor(to); String relType = RelationshipUtils.relationshipTypeUsedFor(to); if (!reversed) { getSession() .addPendingInsert( new RelationshipPendingInsert( entityAccess, relType, new EntityAccess(to.getAssociatedEntity(), propertyValue), getCypherEngine())); } } } else { throw new IllegalArgumentException( "wtf don't know how to handle " + pp + "(" + pp.getClass() + ")"); } } } }