This exception happens because you're running in a Multi Version Control Check (MVCC) system and another thread/user has updated the record you're saving. To fix this problem you can:
If you want to leave the MVCC and write code concurrency proof:
for (int retry = 0; retry < maxRetries; ++retry) {
try {
// APPLY CHANGES
document.field(name, "Luca");
document.save();
break;
} catch(ONeedRetryException e) {
// RELOAD IT TO GET LAST VERSION
document.reload();
}
}
The same in transactions:
for (int retry = 0; retry < maxRetries; ++retry) {
db.begin();
try {
// CREATE A NEW ITEM
ODocument invoiceItem = new ODocument("InvoiceItem");
invoiceItem.field(price, 213231);
invoiceItem.save();
// ADD IT TO THE INVOICE
Collection<ODocument> items = invoice.field(items);
items.add(invoiceItem);
invoice.save();
db.commit();
break;
} catch (OTransactionException e) {
// RELOAD IT TO GET LAST VERSION
invoice.reload();
}
}
Where maxRetries
is the maximum number of attempt of reloading.
(by Raman Gupta) OrientDB uses ServiceRegistry to load OIndexFactory and some OSGi container couldn't be happy with it.
One solution is to set the TCCL so that the ServiceRegistry lookup works inside of osgi:
ODatabaseObjectTx db = null;
ClassLoader origClassLoader = Thread.currentThread().getContextClassLoader();
try {
ClassLoader orientClassLoader = OIndexes.class.getClassLoader();
Thread.currentThread().setContextClassLoader(orientClassLoader);
db = objectConnectionPool.acquire(dbUrl, username, password);
} finally {
Thread.currentThread().setContextClassLoader(origClassLoader);
}
Because the ServiceLoader uses the thread context classloader, you can configure it to use the classloader of the OrientDB bundle so that it finds the entries in META-INF/services.
Another way is to embed the dependencies in configuration in the Maven pom.xml file under plugin(maven-bundle-plugin)/configuration/instructions:
<Embed-Dependency>
orientdb-client,
orient-commons,
orientdb-core,
orientdb-enterprise,
orientdb-object,
javassist
</Embed-Dependency>
Including only the jars you need. Look at Which library do I use?
This is a generic error telling that the database has been found closed while using it.
Check the stack trace to find the reason of it:
This is the case when you're working with Object Database API and a field contains a collection or a map loaded in lazy. On iteration it needs an open database to fetch linked records.
Solutions:
db.save( object )
.This could be due to the high deep of the graph, usually when you create many records. To fix it save the records more often.