Connect SymmetricDS to an Existing H2 Databse File - java

I've a H2 database file which I need to replicate using SymmetricDS.
I can access the database from web console in embedded mode using this url:
jdbc:h2:file:E:/Folder/database;AUTO_SERVER=TRUE;IFEXISTS=TRUE;
But using the same url in node properties file of symmtericds throws following error:
ERROR [server-000] [AbstractSymmetricEngine] [symmetric-engine-startup-0] Could not get a connection to the database: Cannot create PoolableConnectionFactory (IO Exception: "E:/Folder/database outside D:/symmetric-server-3.7.26/tmp/h2" [90028-182]). Waiting for 10 seconds before trying to connect to the database again.
Though if the following url is used in the node properties file of symmetricds, everything works fine but the database is created in symmetric-server-3.7.26/tmp/h2 directory.
jdbc:h2:file:database;AUTO_SERVER=TRUE;
I've not had any luck in solving this issue in past couple of days.
Any kind of help will be greatly appreciated.
Going through H2 documentation I found out that the this behaviour is due to -baseDir option: http://www.h2database.com/html/advanced.html#remote_access .
But how is this option being set automatically and how to disable it..?
Doing some extensive research on the issue, root cause turns out to be the static block of AbstractCommandLauncher class of SymmetricDS:
static {
String symHome = System.getenv("SYM_HOME");
if (symHome == null) {
symHome = ".";
}
System.setProperty("log4j.sym.home", symHome);
if (isBlank(System.getProperty("h2.baseDir"))) {
System.setProperty("h2.baseDir", symHome + "/tmp/h2");
}
DEFAULT_SERVER_PROPERTIES = System.getProperty(SystemConstants.SYSPROP_SERVER_PROPERTIES_PATH, symHome + "/conf/symmetric-server.properties");
log = LoggerFactory.getLogger(AbstractCommandLauncher.class);
initFromServerProperties();
}
And as it turns out, source code of SymmetricDS will have to be modified to resolve it.

This behaviour can not be disabled altogether but overriding it is possible by setting -Dh2.baseDir while running SymmetricDS. The original answer is here

Related

Java sqlite error (error or missing database) no such table

This is the class where I connect sqlite
public static Connection ConnectDB() {
try {
Class.forName("org.sqlite.JDBC");
Connection con= DriverManager.getConnection("jdbc:sqlite:C:\\Users\\abh\\eclipse-workspace \\Training\\Database.db");
return con;
}
catch (Exception e) {
JOptionPane.showMessageDialog(null,e);
return null;
}
}
The jar file inside the project folder name is sqlite-jdbc-3.7.2 I'm confused whether it's because of the version or if it's from my database created in sqlite
SQLite is a pretty good database platform, I highly doubt it's the problem as is the JDBC version your using as well.
The Connection method you presented does indeed work but you need to keep in mind that the connection has nothing to do with tables. It has everything to towards a connection to a particular SQLite database file and if the path doesn't exist to get to the database file specified, then it simply can not find that database. If the path does exist, and local system permissions allow it, and the database file does not exist, then the connection call will automatically create the database file specified but it will be empty. Never the less, the connection is now made and ready for a database Table to be either Created or Accessed via a query (providing there is actual data in the table).
If there was an error regards to the connection then you would receive a Message Box on the screen, and if you do then it's probably because of the whitespace that exists in the specified database path between eclipse-workspace and \\Training:
"jdbc:sqlite:C:\\Users\\abh\\eclipse-workspace \\Training\\Database.db"
Edit: Oh...as already specified by #lazylead :)
On a side: It's not a good idea to hard-code the path to your database file. This will never be the path when the application is run in the real world.

Is it possible to change HSQLDB mode to read-only on the fly?

I am using HSQLBD in file: mode.
(My usage of the HSQLDB is shown in my other question)
I need to receive a multiple-access to the database.script file.
By default, database is running with option readonly=false Here is some information from the official docs:
Readonly Databases
A file: catalog can be made readonly permanently, or it can be opened
as readonly. To make the database readonly, the property, value pair,
readonly=true can be added to the .properties file of the database.
The SHUTDOWN command must be used to close the database before making
this change.
It is also possible to open a normal database as readonly. For this,
the property can be included in the URL of the first connection to the
database.
With readonly databases, it is still possible to insert and delete
rows in TEMP tables.
But I am still not truly understood, is it possible to change this option on the fly, without server shutdown and without restart? If it is possible - can you please give some small code example?
And if not, is there some way to unlock the .script file and get the access for the different threads without the server shutdown?
Your requirement required to access HSQL internal class. The sample code is written for v2.3.3, it may not work for other version.
//import org.hsqldb.*;
//start server
Server.main(new String[]{"-database.0","file:s:/folder/dbname","-dbname.0","dbname","-no_system_exit","true"});
//set DB readonly
Database db = DatabaseManager.lookupDatabaseObject("file:", "s:/folder/dbname");
db.setReadOnly();
//alter connection to readonly
Session[] oa = db.sessionManager.getAllSessions();
for (int i = 0; i < oa.length; i++) {
if (oa[i].getDatabase() == db) {
try {
oa[i].setReadOnly(true);
oa[i].setReadOnlyDefault(true);
} catch (Exception e) {
//the connection is during transaction...
}
}
}
//the implementation of Database cannot turn to writable,
//close it...
db.close(Database.CLOSEMODE_COMPACT);

Accessing MySQL through node-java

So, I have a node.js project that I am working on for a class. One of the features our group is trying to build, requires calling a Java class method that connects to a MySQL database, does some computation and returns the result to the node server. Here is what we have so far:
Using the node-java library, we are adding the required jars to classpath:
var java = require('java');
var path = require('path');
java.classpath.push(path.join(__dirname, "../java/mysql-connector-java.5.1.38-bin.jar"));
java.classpath.push(path.join(__dirname, "../java/BayesianCurve.jar"));
java.classpath.push(path.join(__dirname, "../java/commons-math3-3.6.jar"));
Then, the class is instantiated and a method is called:
var test = java.newInstanceSync('BayesianCurve');
test.getPrediction(param, function(err, data){
if(err)
{
console.log(err);
return;
}
else
res.send(JSON.stringify(data));
});
So far, so good. The Java class method then has to create a connection to a MySQL database and this is where the problems start:
Class.forName("com.mysql.jdbc.Driver");
//System.setProperty("jdbc.drivers","com.mysql.jdbc.Driver");
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
System.out.println("Here");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/schema","root","root");
The java code, standalone, is able to connect to the database and execute queries. However, when used through the node-java module, it throws:
ClassNotFoundException: com.mysql.jdbc.Driver
One reason we thought about was that this library is linked dynamically. Somehow, the java environment in node.js is not able to figure this out. However, we are not really sure how to resolve this. Any help in this regard is appreciated.

How can I get the path of my Neo4j <config storeDirectory=""> in a Batch Inserter method?

I'm using Neo4j 2.2.8 and Spring Data in a web application. I'm using xml to configure my database, like:
<neo4j:config storeDirectory="S:\Neo4j\mybase" />
But I'm trying to use a Batch Inserter to add more than 1 million of nodes sourced from a .txt file. After reading the file and setting the List of objects, my code to batch is something like:
public void batchInserter(List<Objects> objects) {
BatchInserter inserter = null;
try {
inserter = BatchInserters.inserter("S:\\Neo4j\\mybase");
Label movimentosLabel = DynamicLabel.label("Movimentos");
inserter.createDeferredSchemaIndex(movimentosLabel).on("documento").create();
for (Objects objs : objects{
Map<String, Object> properties = new HashMap<>();
properties.put("documento", objs.getDocumento());
long movimento = inserter.createNode(properties, movimentosLabel);
DynamicRelationshipType relacionamento = DynamicRelationshipType.withName("CONTA_MOVIMENTO");
inserter.createRelationship(movimento, objs.getConta().getId(), relacionamento, null);
}
} finally {
if (inserter != null) {
inserter.shutdown();
}
}
}
Is it possible to get the path of my database configured in my xml in the "inserter"? Because with the above configuration Neo4j gives me an error about multiple connections. Can I set a property to solve this error of multiple connections? Has anyone had this problem and have any idea how to solve it? Ideas are welcome.
Thanks to everyone!
Your question has several pieces to it:
Error About Multiple Connections
If you're using spring-data with a local database tied to a particular directory or file, be aware that you can't have two neo4j processes opening the same DB at the same time. This means that if you've decided to use BatchInserter against the same file/directory, this cannot happen at all while the JVM that's using the spring-data DB is running. There won't be a way I know of to get around that problem. One option would be to not use the batch inserter against the file, but to use the REST API to do inserting.
get the path of my database configured in my xml
Sure, there's a way to do that, you'd have to consult the relevant documentation. I can't give you the code for that because it depends on which config file your'e talking about and how it's structured, but in essence there should be a way to inject the right thing into your code here, and read the property from the XML file out of that injected object.
But that won't help you given your "Multiple connections" issue mentioned above.
Broadly, I think your solution is either:
Don't run your spring app and your batch inserter at the same time.
Run your spring app, but do insertion via the REST API or other method, so there isn't a multiple connection issue to begin with.

Can't use MySql for Spring Greenhouse project?

I just checked out the Spring Greenhouse project as a first step to learn Spring Security.
The project works fine but I was wondering about the following scenarios:
There are two configurations: standard and embedded. The javadoc says the embedded is default. I am not sure how to make it run in standard mode. Has anybody has tried this before?
Secondly in embedded mode I modified the code slightly with the following code to run it with MySql but to my surprise the application is not starting up at all. It throws the following error:
throw new RuntimeException("Unable to determine database version", e);
#Bean(destroyMethod="shutdown")
public DataSource dataSource() {
// EmbeddedDatabaseFactory factory = new EmbeddedDatabaseFactory();
// factory.setDatabaseName("greenhouse");
// factory.setDatabaseType(EmbeddedDatabaseType.);
DriverManagerDataSource mysqldataSource = new DriverManagerDataSource();
mysqldataSource.setDriverClassName("com.mysql.jdbc.Driver");
mysqldataSource.setUrl("jdbc:mysql://localhost/greenhouse?useConfigs=maxPerformance&characterEncoding=utf8");
mysqldataSource.setUsername("root");
mysqldataSource.setPassword("mysql");
return populateDatabase(mysqldataSource);
}
Can anybody please help me on this?
I figured it out by myself.
There was a tag in web.xml and i changed there from embedded to standard.
The problem was in the sql query which was creating the database version table was not mysl complaint. There were other queries also which were not mysql complaint. I changed the sql query and now eveything worked like as expected. The next thing I am gonna do is use some kind og generic database query generator so that i don't have to change the query if in future I change my mind to use post gre sql in place of my sql.
Thank you for all your help and support.
Judging by the exception you're getting, the file you're interested in is GenericDatabaseUpgrader.java
More than half the code there refers to DatabaseVersion which is a table that is created if absent.
Since I doubt you already have it and judging by the exception type (SQLException), I'm inclined to say it's failing to create/insert/retrieve the referenced table.
You can check if you have the table and go from there.
Also, judging by the code you're trying to inject, I'd also look at connection = dataSource.getConnection() as a possible culprit.
P.S. Regarding standard/embedded, it appears you can VM parameters or maven settings to switch between the two. Please check the official forums and specifically this topic for info

Categories