Use bolt driver and Java API of Neo4j simultaneously - java

Hello everybody!
I have developed a JavaFX application to support my scientific work (molecular biology/neuropharmacology), implementing Neo4j, at the time Version 2.x.
Now, since Version 3 (using 3.1.0-M05) is out, I am switching over to Bolt protocol access of the Database, with the Driver (1.1.0-M01) interface. Some functions of my application still require Java API access though, so I cannot completely abandon the old code. I am using a singleton GraphDatabaseFactory to start up the database, like so
private static GraphDatabaseService instance;
private GraphDb() {
instance = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(new File(FilePaths.DATABASE_PATH))
.setConfig(ShellSettings.remote_shell_enabled, "true").newGraphDatabase();
}
public static synchronized GraphDatabaseService getInstance() {
return instance;
}
(Or, just the .newEmbeddedDatabase())But now, since Version 3, I also use a singleton Driver instance for the Bolt interaction, like so
private static Driver instance;
private GraphDbDriver() {
startLocalDb();
instance = GraphDatabase.driver("bolt://localhost");
}
private static void startLocalDb() {
//start database here?
}
public static synchronized Driver getInstance() {
return instance;
}
My question now, is this (since I gathered that using both at the same time can only breed complications): How do I use these two ways of communicating with the DB without them getting in the way of each other?
Can I somehow get the Driver to load "onto" the already created GraphDatabaseService singleton?
Thanks for reading!

So, for anybody who's interested, in Neo4j 3.x it is recommended to use 'User-defined procedures' to implement API commands (like, e.g., traversals) and then calling it (via CALL) from cypher.

Related

Java resource clean up before object destruction

I've the following problem and I know there are already a lot of questions but none of these give me really a satisfactorily answer! I wrote a lot of stuff in C++ and this language provide a destructor, Java doesn't because of the garbage collection.
A little introduction in my situation: I wrote a software which is accessing a local Sqlite3 database. I wrote a central singleton class for accessing this database. Multiple other classes access the DB through this wrapper class. Here is the pseudo-code of this wrapper class:
public class MyDbWrapper
{
private currentDbConnection;
public MyDbWrapper(dbPath)
{
// Open the database connection with given path
}
public readFromDb()
{
... // Uses the class member currentDbConnection
}
public writeToDb()
{
... // Uses the class member currentDbConnection
}
public closeDb()
{
...
}
}
Now my question is, how could I ensure that the database connection is closed before quitting the application? Yes I already implemented the AutoCloseable interface and yes I worked already a lot with try-with-resources, but because of the access by multiple classes this isn't really an option!
In C++ a destructor would solve this issue, but the possible "equivalent" in java the method finalize is deprecated!
So are there any other options or should I totally re-design my complete wrapper? If yes, how could I prevent performance issues because of a lot of read write access if I re-open the database every time?
Like Joker_vD already said, I solved this issue by using a try-with-resources statement in the main method of my program...
public static void main(String [] args)
{
try(MyDbWrapper wrapper = new MyDbWrapper())
{
// Execute other task with usage of the database wrapper
}
}
With this solution there is no need for a desturctor or the usage of the deprecated method finalize(), the database connection get closed if program ends...
Thanks again and credits to Joker_vD

Proper Vertx database etiquette

I'm fairly new to Vertx, And trying to find some realistic examples of database usage.
I have a Verticle that creates a shared database object (And a number of classes that handle routing, but I would like to use the shared database outside the main class, obviously I could pass the database object in other classes constructors, but I'm sure Vertx has some better way to do this.
public void start() {
...
this.postgreSQLClient = PostgreSQLClient.createShared(vertx, sqlClientConfig);
...
}
Does anyone have any Java Vertx examples with realistic implementations of a database?
Thank you in advance.
Use Dependency Injection. I have used Guice
Here's the example of it:
Main.java
//within main function where you have object of vertx
Guice.createInjector(new AppInjector(vertx));
AppInjector.java
//Create an Injector file and bind your injections
PostgreSQLClient postgreSQLClient = PostgreSQLClient.createShared(vertx, sqlClientConfig, "my-shared-client");
bind(PostgreSQLClient.class).annotatedWith(Names.named("DBClient")).toInstance(postgreSQLClient);
UserService.java
public class UserService {
#Inject
#Named("DBClient")
private PostgreSQLClient client;
}
You can find the source code here
Just specify a pool name:
if different clients are created using the same Vert.x instance and
specifying the same pool name, they will share the same data source.
So updating your example:
public void start() {
this.postgreSQLClient = PostgreSQLClient.createShared(vertx, sqlClientConfig, "my-shared-client");
}
Note that when doing this, the configuration provided in the first call will be used. Subsequent calls will simply return the existing client.

Using a homemade library of classes as functions in other class files

I am fairly new to Java so forgive me if this is a silly question, but believe me when I say I really cannot find a solid answer.
This is what I'm working with:
So I'm testing a program, and the easiest way to keep it maintained and updated is to create my own library of "buttons". Everything in the library are small functions like "enterValidCredentials" and "clickLoginButton".
So let's take a look at my test cases. In a perfect world I'd be able to just:
public class progressCheck {
public static void main(String[] args) {
WebDriver driver = new FirefoxDriver();
driver.get("http://mail.google.com/");
enterValidCredentials;
clickLoginButton;
}
}
enterValidCredentials and clickLoginButton exist in my library of classes. I know very well that that's not going to work as written above. What, literally, is the correct way to do this?
If it helps at all, my enterValidCredentials class looks like this:
public class loginPageButtons {
private WebDriver driver;
Actions actions = new Actions(driver);
public class enterValidCredentials { // This class enters in a valid username and valid password on the login page.
public void enterValidCredentials2() {
driver.findElement(By.cssSelector("input[type=\"text\"]")).clear();
driver.findElement(By.cssSelector("input[type=\"text\"]")).sendKeys("XXXXXXXX");
driver.findElement(By.cssSelector("input[type=\"password\"]")).clear();
driver.findElement(By.cssSelector("input[type=\"password\"]")).sendKeys("XXXXXXXX");
}
}
All my other functions follow a relatively similar structure (depending on their function, of course).
You can use a unit test to check single functionalities of your classes.
The most used library to create unit tests is JUnit.
If you use an ide (like IntelliJ or Eclipse) running the test can be done with a simple command exactly as running a main method.
If you need to create mocks of your objects you can use a library like Mockito (but there are many other valid alternatives).
Note: A mock is an object that has the same interface as a complex object that is difficult to use in a test environment (for example a db connection, a file handler, a network handler).
Here is an example, I tried to imagine your code and a possible test. I assumed that clickLoginButton returns an integer just to show a possible assert statement.
Example:
#Test
public static void testCredentials() {
WebDriver driver = new FirefoxDriver();
driver.get("http://mail.google.com/");
EnterValidCredentials enterValidCredentials = new EnterValidCredentials(); // Or create a mock if necessary
// Set values if necessary
int returnValue = enterValidCredentials.clickLoginButton();
assertEquals(returnValue, 1);
}

Correct use of static

Currently I am using mongodb with java. I don't want to reopen my connection to the datastore every time, so I thought I should make a static variable:
package Config;
import java.net.UnknownHostException;
import com.google.code.morphia.*;
import com.mongodb.Mongo;
import com.mongodb.MongoException;
public class Config {
static String dbUrl = "url";
static int dbPort = portnumber;
static String username = "user";
static String password = "pw";
static String dbName = "dbname";
public static Datastore ds;
public static Datastore getDatastore() throws UnknownHostException,
MongoException {
if (ds == null) {
ds = connect();
}
return ds;
}
public static Datastore connect() throws UnknownHostException,
MongoException {
Mongo m = new Mongo(dbUrl, dbPort);
Datastore ds = new Morphia().createDatastore(m, dbName);
boolean con = ds.getDB().authenticate(username, password.toCharArray());// todo
return ds;
}
}
I would use it like this:
Config.getDatastore().doSomthing();
Beside those un-handled exceptions, is this the correct way of using a static variable?
Better would be making Config class as a singleton.
The given Config seems to indicate that this class should be a singleton, and if so, then using static variables for all members is fine. Will you have multiple Configs, or only one?
If Config isn't intended to be a singleton, then static isn't required in this case, or if so, only if it's ok to share your Datastore with every instance of your Config class. You'll achieve your goals with a simple - non-static - member variable, and you can still have, e.g. a getDataStore method. But each Config class will have it's own Datastore
Only use static if you want to also share that Datastore among multiple instances of your Config class.
is this the correct way of using a static variable?
well, your code seems to compile so as per the language its correct. As far as semantics are concerned the usage depends. it depends on the class in questions, the design you want to achieve.
I would personally go for a connection pool. If several connections are not required, i may go for a singleton if i need to maintain only one connection. If a single connection is not required i would go with a member variable.
In your case, it would depend on how you want to use the config class. In general design terms, what you have done is problematic for following reasons:
Everything is static in your class, it serves no purpose in terms of object oriented-ness.
You can not unit test this class unless you use powermock or some other framework.
what happens when someone calls connect() several times?
*Note: Singleton is an anti-pattern. Generally any global state is bad. I would avoid it as much as i can.

makePersistent failing with JDO

I have the following code deployed to an app engine server (the only
place where I can test JDO, unfortunately I cannot test JDO locally
because I don't have a local BigTable implementation).
final class PMF {
private static final PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory("transactions-optional");
private PMF() { }
public static PersistenceManagerFactory get() { return pmf; }
}
#PersistenceCapable
class Data {
// ...
#Persistent
private static List<Store> stores = new ArrayList<Store>();
static List<Store> getStores() {
return stores;
}
}
...
Data.getStores().add(store);
writer.write("this line received OK by client.");
PMF.get().getPersistenceManager().makePersistent(Data.getStores());
writer.write("this line never received by client.");
As shown the first line of output from the server is received on the client and the second one is not which means makePersistent() is failing.
Anyone have any idea why this is happening?
Perhaps the simple fact that no standard persistence API for Java provides persistence of static fields.
You can mimic BigTable on your local machine by running your code locally using ant or the eclipse appengine plugin. The eclipse plugin also runs datanucleus in the background and will catch errors like this for you without having to upload to appengine whenever you make a change.

Categories