I'm trying to access my database while using SqlJet Transactions, but I get this error all the time
org.tmatesoft.sqljet.core.SqlJetException: MISUSE: error code is MISUSE
Here is my code:
SqlJetDb db = null;
try {
File dbFile = new File(Configuration.DATABASE_NAME);
db = SqlJetDb.open(dbFile, true);
db.getOptions().setAutovacuum(true);
db.beginTransaction(SqlJetTransactionMode.READ_ONLY);
ISqlJetTable table = db.getTable("customers");
ISqlJetCursor cursor = table.order(table.getPrimaryKeyIndexName());
if (!cursor.eof()) {
do {
getInitData(cursor);
} while (cursor.next());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
db.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
Does anybody know what's wrong with the issue? Due to this list, the actuall library usage was improper, but I've checked it out and there wasn't anything wrong to me. http://grepcode.com/file/repo1.maven.org/maven2/org.tmatesoft.sqljet/sqljet/1.0.2/org/tmatesoft/sqljet/core/SqlJetErrorCode.java#SqlJetErrorCode
Thanks!
It happens because you are trying to open a DB that is already opened by another process .
it happened to me because the db was opened by Firefox SQLite Manager, but basically it could happen by any other thread or process accessing your DB .
Related
I am using following code to iterate through a database's documents.
public void readDataStore() throws IOException {
Query query = document_datastore.find(DocumentPojo.class);
List<DocumentPojo> documentPojos = query.asList();
documentPojos.forEach(obj -> {
try {
System.out.println(obj.getDocid());
} catch (IOException e) {
e.printStackTrace();
}
}
);
}
Currently the DB has not more than 100 documents but in future it can have ~100000 documents. I suspect then it may run into performance issues?
DocumentPojo is the class that I map the results to. I am using Java 8 and Morphia.
How should I solve this issue?
Use query.fetch() to get the MorphiaIterator and then handle each document as you get it. It won't pull them all in to memory at once allowing you to process your hundred thousand+ documents.
One way of implementing #evanchooly's answer:
public void readDataStore() throws IOException {
final Query query = document_datastore.find(DocumentPojo.class);
query.fetch().forEach(obj -> {
try {
System.out.println(obj.getDocid());
} catch (final IOException e) {
e.printStackTrace();
}
});
}
I am getting a
org.hibernate.TransactionException: nested transactions not supported
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:152)
at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1395)
at com.mcruiseon.server.hibernate.ReadOnlyOperations.flush(ReadOnlyOperations.java:118)
Code that throws that exception. I am calling flush from a thread that runs infinite until there is data to flush.
public void flush(Object dataStore) throws DidNotSaveRequestSomeRandomError {
Transaction txD;
Session session;
session = currentSession();
// Below Line 118
txD = session.beginTransaction();
txD.begin() ;
session.saveOrUpdate(dataStore);
try {
txD.commit();
while(!txD.wasCommitted()) ;
} catch (ConstraintViolationException e) {
txD.rollback() ;
throw new DidNotSaveRequestSomeRandomError(dataStore, feedbackManager);
} catch (TransactionException e) {
txD.rollback() ;
} finally {
// session.flush();
txD = null;
session.close();
}
// mySession.clear();
}
Edit :
I am calling flush in a independent thread as datastore list contains data. From what I see its a sync operation call to flush, so ideally flush should not return until transaction is complete. I would like it that way is the least I want to expect. Since its a independent thread doing its job, all I care about it flush being a sync operation. Now my question is, is txD.commit a async operation ? Does it return before that transaction has a chance to finish. If yes, is there a way to get commit to "Wait" until the transaction completes ?
public void run() {
Object dataStore = null;
while (true) {
try {
synchronized (flushQ) {
if (flushQ.isEmpty())
flushQ.wait();
if (flushQ.isEmpty()) {
continue;
}
dataStore = flushQ.removeFirst();
if (dataStore == null) {
continue;
}
}
try {
flush(dataStore);
} catch (DidNotSaveRequestSomeRandomError e) {
e.printStackTrace();
log.fatal(e);
}
} catch (HibernateException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Edit 2 : Added while(!txD.wasCommitted()) ; (in code above), still I get that freaking nested transactions not supported. Infact due to this exception a record is not being written to by table too. Is there something to do with the type of table ? I have INNODB for all my tables?
Finally got the nested transaction not supported error fixed. Changes made to code are
if (session.getTransaction() != null
&& session.getTransaction().isActive()) {
txD = session.getTransaction();
} else {
txD = session.beginTransaction();
}
//txD = session.beginTransaction();
// txD.begin() ;
session.saveOrUpdate(dataStore);
try {
txD.commit();
while (!txD.wasCommitted())
;
}
Credits of above code also to Venkat. I did not find HbTransaction, so just used getTransaction and beginTransaction. It worked.
I also made changes in the hibernate properties due to advice on here. I added these lines to the hibernate.properties. This alone did not solve the issue. But I am leaving it there.
hsqldb.write_delay_millis=0
shutdown=true
You probably already began a transaction before calling this method.
Either this should be part of the enclosing transaction, and you should thus not start another one; or it shouldn't be part of the enclosing transaction, and you should thus open a new session and a new transaction rather than using the current session.
I am trying to configure a database for an application I am writing. I have started up the OrientDB server and have created a database, as well as a username and password. I hope to be able to tie my application to this, but I am currently in testing phases.
Here is the test:` static OObjectDatabaseTx db;
static people.Group group;
public static void main(String[] args)
{
try {
db = new OObjectDatabaseTx("local:/Users/<me>/Documents/Java/OrientDB/Sources/releases/orientdb-1.3.0-SNAPSHOT/databases/people");
System.out.println("db made");
db.open("nick", "nick");
System.out.println("db open");
group = new people.Group();
System.out.println("group made");
db.save(group);
System.out.println("group saved");
System.out.println(group);
} catch (Exception e) {
System.out.println("Not succeed - " + e.getMessage());
e.printStackTrace();
} finally {
if( db != null ) {
db.close();
}
}
}`
and when run, the output:
db made
Not succeed - Cannot open local storage '/Users//Documents/Java/OrientDB/Sources/releases/orientdb-1.3.0-SNAPSHOT/databases/people' with mode=rw
com.orientechnologies.orient.core.exception.OStorageException: Cannot open local storage '/Users//Documents/Java/OrientDB/Sources/releases/orientdb-1.3.0-SNAPSHOT/databases/people' with mode=rw
at com.orientechnologies.orient.core.storage.impl.local.OStorageLocal.open(OStorageLocal.java:204)
at com.orientechnologies.orient.core.db.raw.ODatabaseRaw.open(ODatabaseRaw.java:93)
at com.orientechnologies.orient.core.db.ODatabaseWrapperAbstract.open(ODatabaseWrapperAbstract.java:47)
at com.orientechnologies.orient.core.db.record.ODatabaseRecordAbstract.open(ODatabaseRecordAbstract.java:111)
at com.orientechnologies.orient.core.db.ODatabaseWrapperAbstract.open(ODatabaseWrapperAbstract.java:47)
at com.orientechnologies.orient.core.db.ODatabaseWrapperAbstract.open(ODatabaseWrapperAbstract.java:47)
at com.orientechnologies.orient.object.db.OObjectDatabaseTx.open(OObjectDatabaseTx.java:99)
at db.ToFromByte.main(ToFromByte.java:34)
Caused by: com.orientechnologies.orient.core.exception.OSerializationException: Cannot load database's configuration. The database seems to be corrupted.
at com.orientechnologies.orient.core.storage.impl.local.OStorageConfigurationSegment.load(OStorageConfigurationSegment.java:73)
at com.orientechnologies.orient.core.storage.impl.local.OStorageLocal.addDefaultClusters(OStorageLocal.java:215)
at com.orientechnologies.orient.core.storage.impl.local.OStorageLocal.open(OStorageLocal.java:143)
... 7 more
So the code fails on this line of code: db.open("nick", "nick");
What could be happening here? The database seems to be accessible through the OrientDB server.
Probably the database is corrupted right now because both server and local run concurrently?
EDIT:
Found the solution. It was a problem with minifing the code while maven build process. Run the OrientDB in a Java Applet is possible.
I have problems starting the inmemory OrientDB in a Java Applet. I use a signed Applet with OrientDB version 1.0.1. Did someone implemented the OrientDB in a Applet and can verify that this is possible or could help me with this exception?
The exception I get:
2012-06-20 11:22:24:734 INFO OrientDB Server v1.0.1 is starting up... [OServer]Exception in thread "thread applet-de.test.all.Applet-1" sun.misc.ServiceConfigurationError: com.orientechnologies.orient.core.sql.OCommandExecutorSQLFactory: Provider com.orientechnologies.orient.core.sql.ODefaultCommandExecutorSQLFactory not found
at sun.misc.Service.fail(Service.java:129)
at sun.misc.Service.access$000(Service.java:111)
at sun.misc.Service$LazyIterator.next(Service.java:273)
at com.orientechnologies.orient.core.sql.OSQLEngine.getCommandFactories(OSQLEngine.java:186)
at com.orientechnologies.orient.core.sql.OSQLEngine.getCommandNames(OSQLEngine.java:216)
at com.orientechnologies.orient.core.sql.OSQLEngine.getCommand(OSQLEngine.java:239)
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLDelegate.parse(OCommandExecutorSQLDelegate.java:41)
at com.orientechnologies.orient.core.sql.OCommandExecutorSQLDelegate.parse(OCommandExecutorSQLDelegate.java:31)
at com.orientechnologies.orient.core.storage.OStorageEmbedded.command(OStorageEmbedded.java:62)
at com.orientechnologies.orient.core.command.OCommandRequestTextAbstract.execute(OCommandRequestTextAbstract.java:60)
at com.orientechnologies.orient.core.metadata.schema.OSchemaShared.createClass(OSchemaShared.java:218)
at com.orientechnologies.orient.core.metadata.schema.OSchemaShared.createClass(OSchemaShared.java:164)
at com.orientechnologies.orient.core.metadata.schema.OSchemaShared.createClass(OSchemaShared.java:145)
at com.orientechnologies.orient.core.metadata.schema.OSchemaShared.createClass(OSchemaShared.java:116)
at com.orientechnologies.orient.core.metadata.schema.OSchemaProxy.createClass(OSchemaProxy.java:65)
at com.orientechnologies.orient.core.metadata.security.OSecurityShared.createMetadata(OSecurityShared.java:259)
at com.orientechnologies.orient.core.metadata.security.OSecurityShared.create(OSecurityShared.java:202)
at com.orientechnologies.orient.core.metadata.security.OSecurityProxy.create(OSecurityProxy.java:37)
at com.orientechnologies.orient.core.metadata.OMetadata.create(OMetadata.java:68)
at com.orientechnologies.orient.core.db.record.ODatabaseRecordAbstract.create(ODatabaseRecordAbstract.java:171)
at com.orientechnologies.orient.core.db.ODatabaseWrapperAbstract.create(ODatabaseWrapperAbstract.java:53)
at com.orientechnologies.orient.core.db.ODatabaseRecordWrapperAbstract.create(ODatabaseRecordWrapperAbstract.java:54)
at com.orientechnologies.orient.server.OServer.loadStorages(OServer.java:451)
at com.orientechnologies.orient.server.OServer.loadConfiguration(OServer.java:394)
at com.orientechnologies.orient.server.OServer.startup(OServer.java:152)
at com.orientechnologies.orient.server.OServer.startup(OServer.java:143)
at com.orientechnologies.orient.server.OServer.startup(OServer.java:132)
at de.test.all.Applet$1.run(Applet.java:132)
at de.test.all.Applet$1.run(Applet.java:125)
at java.security.AccessController.doPrivileged(Native Method)
at de.test.all.Applet.init(Applet.java:124)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Plugin2Manager.java:1639)
at java.lang.Thread.run(Thread.java:680)
My Applet code to start the DB:
public class Applet extends java.applet.Applet {
OrientDbConfigurationLoader configLoader = null;
OServer server = null;
ODatabaseDocumentTx db = null;
#Override
public void init() {
AccessController.doPrivileged(new
PrivilegedAction<OServer>() {
public OServer run() {
configLoader = new OrientDbConfigurationLoader("db/", "test");
try {
server = OServerMain.create();
server.startup(configLoader.loadDefaultConfig());
server.activate();
} catch (InstanceAlreadyExistsException e) {
server = OServerMain.server();
} catch (Exception e) {
System.out.println("Something went wrong while the server should start");
e.printStackTrace();
}
try {
db = new ODatabaseDocumentTx("memory:temp");
db = db.open(OrientDbConfigurationLoader.USERNAME, OrientDbConfigurationLoader.PASSWORD);
} catch (Exception e) {
System.out.println("Can't init the in-memory db.");
e.printStackTrace();
}
return null;
}
});
}
}
the problem seems the usage of Java Service Registry. Look at:
OClassLoaderHelper.lookupProviderWithOrientClassLoader()
it calls:
ServiceRegistry.lookupProviders(clazz);
I've just added in SVN trunk (r5909) this check:
try {
factories.add(ite.next());
} catch (Exception e) {
OLogManager.instance().warn(null, "Cannot load OCommandExecutorSQLFactory instance from service registry", e);
}
In this way a WARN is dumped but you can continue to configure your own factories if needed.
Hi I'm trying to clean up my code to remove errors stating that my db connection was opened but not closed correctly.
If I have a db.open() then a few try catch statements around db query's then a db.close() following the try catch will it use the same db connection within the try catches or does java discretely run the try catch statements so the db connection is not available.
In short, should i have code something like this:
db.open();
try {
// here
db.getThings()
} catch () {
// there
}
try {
// here 2
db.getMoreThings()
} catch () {
// there 2
}
db.close();
Or this:
try {
// here
db.open();
db.getThings()
db.close();
} catch () {
// there
}
try {
// here 2
db.open();
db.getMoreThings()
db.close();
} catch () {
// there 2
}
I'd have thought the first solution of opening one db connection is the better one. But i'm running into issues with not closing db connections and i'm at the point of thinking there's a fundamental issue with my design.
I've also tried opening the connection in onResume() then close in onPause() but still having problems.
There is a recommendation to close DB connection as soon as you selected data, so in my app I mainly use the following template:
db.open();
try {
// select data
} finally {
db.close();
}
it worked for me.