public void index(final Object primaryKey, final List foreignKeys) { // if the association is a unidirectional one-to-many we store the keys // embedded in the owning entity, otherwise we use a foreign key if (!association.isBidirectional()) { mongoTemplate.execute( new DbCallback<Object>() { public Object doInDB(DB db) throws MongoException, DataAccessException { List dbRefs = new ArrayList(); for (Object foreignKey : foreignKeys) { if (isReference) { dbRefs.add( new DBRef( db, getCollectionName(association.getAssociatedEntity()), foreignKey)); } else { dbRefs.add(foreignKey); } } nativeEntry.put(association.getName(), dbRefs); if (primaryKey != null) { final DBCollection collection = db.getCollection(getCollectionName(association.getOwner())); DBObject query = new BasicDBObject(MONGO_ID_FIELD, primaryKey); collection.update(query, nativeEntry); } return null; } }); } }
public List query(Object primaryKey) { // for a unidirectional one-to-many we use the embedded keys if (!association.isBidirectional()) { final Object indexed = nativeEntry.get(association.getName()); if (indexed instanceof Collection) { if (indexed instanceof List) return (List) indexed; return new ArrayList((Collection) indexed); } return Collections.emptyList(); } // for a bidirectional one-to-many we use the foreign key to query the inverse side of the // association Association inverseSide = association.getInverseSide(); Query query = session.createQuery(association.getAssociatedEntity().getJavaClass()); query.eq(inverseSide.getName(), primaryKey); query.projections().id(); return query.list(); }
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() + ")"); } } } }