/** * Deletes the specified object from the object set. * * <p>{@inheritDoc} * * @throws NotFoundException if the specified object could not be found. * @throws ForbiddenException if access to the object is forbidden. * @throws ConflictException if version is required but is {@code null}. * @throws PreconditionFailedException if version did not match the existing object in the set. */ @Override public ResourceResponse delete(DeleteRequest request) throws ResourceException { if (request.getResourcePathObject().size() < 2) { throw new NotFoundException( "The object identifier did not include sufficient information to determine the object type and identifier of the object to update: " + request.getResourcePath()); } if (request.getRevision() == null || "".equals(request.getRevision())) { throw new ConflictException( "Object passed into delete does not have revision it expects set."); } final String type = request.getResourcePathObject().parent().toString(); final String localId = request.getResourcePathObject().leaf(); int ver = DocumentUtil.parseVersion( request.getRevision()); // This throws ConflictException if parse fails ODatabaseDocumentTx db = getConnection(); try { ODocument existingDoc = predefinedQueries.getByID(localId, type, db); if (existingDoc == null) { throw new NotFoundException( "Object does not exist for delete on: " + request.getResourcePath()); } db.delete(existingDoc.getIdentity(), new OSimpleVersion(ver)); logger.debug("delete for id succeeded: {} revision: {}", localId, request.getRevision()); return DocumentUtil.toResource(existingDoc); } catch (ODatabaseException ex) { // Without transaction the concurrent modification exception gets nested instead if (isCauseConcurrentModificationException(ex, 10)) { throw new PreconditionFailedException( "Delete rejected as current Object revision is different than expected by caller, the object has changed since retrieval. " + ex.getMessage(), ex); } else { throw ex; } } catch (OConcurrentModificationException ex) { throw new PreconditionFailedException( "Delete rejected as current Object revision is different than expected by caller, the object has changed since retrieval." + ex.getMessage(), ex); } catch (RuntimeException e) { throw e; } finally { if (db != null) { db.close(); } } }
@Test public void testTransactionPopulateDelete() { ODatabaseDocumentTx db = new ODatabaseDocumentTx(url); db.open("admin", "admin"); if (!db.getMetadata().getSchema().existsClass("MyFruit")) { OClass fruitClass = db.getMetadata().getSchema().createClass("MyFruit"); fruitClass.createProperty("name", OType.STRING); fruitClass.createProperty("color", OType.STRING); fruitClass.createProperty("flavor", OType.STRING); db.getMetadata() .getSchema() .getClass("MyFruit") .getProperty("name") .createIndex(OClass.INDEX_TYPE.NOTUNIQUE); db.getMetadata() .getSchema() .getClass("MyFruit") .getProperty("color") .createIndex(OClass.INDEX_TYPE.NOTUNIQUE); db.getMetadata() .getSchema() .getClass("MyFruit") .getProperty("flavor") .createIndex(OClass.INDEX_TYPE.NOTUNIQUE); } db.close(); db = new ODatabaseDocumentTx(url); db.open("admin", "admin"); int chunkSize = 500; for (int initialValue = 0; initialValue < 10; initialValue++) { System.out.println("initialValue = " + initialValue); Assert.assertEquals(db.countClusterElements("MyFruit"), 0); // do insert Vector<ODocument> v = new Vector<ODocument>(); db.begin(); for (int i = initialValue * chunkSize; i < (initialValue * chunkSize) + chunkSize; i++) { ODocument d = new ODocument("MyFruit") .field("name", "" + i) .field("color", "FOO") .field("flavor", "BAR" + i); d.save(); v.addElement(d); } System.out.println("populate commit"); db.commit(); // do delete db.begin(); System.out.println("vector size = " + v.size()); for (int i = 0; i < v.size(); i++) { db.delete(v.elementAt(i)); } System.out.println("delete commit"); db.commit(); Assert.assertEquals(db.countClusterElements("MyFruit"), 0); } db.close(); }