typedb / typedb-docs

TypeDB Documentation
25 stars 72 forks source link

Document how to delete while iterating over concepts #466

Open lolski opened 3 years ago

lolski commented 3 years ago

Trying to delete concepts as you iterate over them will fail with a ConcurrentModificationException:

try (Grakn.Session session = grakn.session(database, Arguments.Session.Type.DATA)) {
                try (Grakn.Transaction tx = session.transaction(Arguments.Transaction.Type.WRITE)) {
                    tx.query().insert(Graql.parseQuery("insert $x true isa property;"));
                    tx.query().insert(Graql.parseQuery("insert $x false isa property;"));
                    Stream<? extends Attribute> properties = tx.concepts().getAttributeType("property").getInstances().limit(10);
                    properties.forEach(e -> { // the 2nd iteration will fail because the original collection has been modified by the delete() from the 1st iteration
                        e.delete();
                    });
                    tx.commit();
                }
            }

Instead, the user should collect the concepts onto a separate list and iterate over them:

        try (Grakn grakn = RocksGrakn.open(directory)) {
            grakn.databases().create(database);

            try (Grakn.Session session = grakn.session(database, Arguments.Session.Type.SCHEMA)) {
                try (Grakn.Transaction tx = session.transaction(Arguments.Transaction.Type.WRITE)) {
                    tx.query().define(Graql.parseQuery("define property sub attribute, value boolean;"));
                    tx.commit();
                }
            }

            try (Grakn.Session session = grakn.session(database, Arguments.Session.Type.DATA)) {
                try (Grakn.Transaction tx = session.transaction(Arguments.Transaction.Type.WRITE)) {
                    tx.query().insert(Graql.parseQuery("insert $x true isa property;"));
                    tx.query().insert(Graql.parseQuery("insert $x false isa property;"));
                    List<? extends Attribute> properties = tx.concepts().getAttributeType("property").getInstances().limit(10).collect(Collectors.toList());
                    for (Attribute t: properties) {
                        t.delete();
                    }
                    tx.commit();
                }
            }
        }
haikalpribadi commented 3 years ago

actually, the right solution is to just use Graql Delete query. But yes we should explain this in the documentation.