Load csv file in neo4j embedded in Java - java

I have a neo4j embedded DB in my application and I want to load a .csv file to fill the database. I've managed to create the .csv file in the /import folder but when I try to load it, I get a Couldn't load the external resource at: file:/csv_file.csv.
I've read it may be something about permissions but I cannot change them since it creates the whole folder structure every time I run my application (I try to change them after creating the file with Runtime.getRuntime().exec("chmod 777 /path_to_file/csv_file.csv") but it never works)
This is my code:
public void addCSVtoDB() {
try ( Transaction ignored = graphDb.beginTx();
Result result = graphDb.execute( "LOAD CSV WITH HEADERS FROM \"file:///csv_file.csv\" AS csvLine\n" )
{
}
I'm using MacOSX 10.11 so the / are supposed to be allright. Any idea?

Ok so I finllay solved it: everywhere it says that the .csv files had to be in the /import folder but that doesn't applies to embedded databases. The path_to_file is absolute so I put the .csv file in my /users/MY_USER/ folder and made the cypher query as follows:
public void addCSVtoDB() {
try ( Transaction ignored = graphDb.beginTx();
Result result = graphDb.execute( "LOAD CSV WITH HEADERS FROM \"file:////Users/My_User/csv_file.csv\" AS csvLine\n" )
{
}

Related

Is it possible to get the directory of a class package within a .jar?

I am trying to get the directory of a class package as a File within my .jar (the hierarchy is /controller/core):
File directory_file_of_package = new File(getClass().getResource("/controller/core").toURI());
Which works when I run the program within the IDE, but when I run it as a standalone .jar, it gives me this error:
java.lang.IllegalArgumentException: URI is not hierarchical
Looking at these questions (why my URI is not hierarchical? and Java Jar file: use resource errors: URI is not hierarchical) does not help me, because those questions involved obtaining a File within the .jar as a resource (getResourceAsStream()), but what I am trying to obtain is a directory.
Further, the accepted answer states this:
Generally the IDEs separates on file system classes and resources. But when the jar is created they are put all together.
So, is there no way to grab the directory of /controller/core?
My XY Problem:
I am trying to read a .CSV file using CSVJDBC (http://csvjdbc.sourceforge.net/), and the way the DriverManager references the CSV file as as if the containing folder is the database and the CSV file is the table.
public class SearchData {
void SearchData() {
try {
Class.forName("org.relique.jdbc.csv.CsvDriver");
File directory_file_of_package_containing_csv = new File(getClass().getResource("/controller/core").toURI());
// Driver points to directory which contains the CSV file as if it is the database
Connection conn = DriverManager.getConnection("jdbc:relique:csv:" + directory_file_of_package_containing_csv.toString());
System.out.println("Connection established.");
Statement stmt = conn.createStatement();
System.out.println("Statement created.");
// CSV is named "data.csv" so the CsvDriver sees "data" as the table name
String sql = "SELECT id,name FROM data";
ResultSet results = stmt.executeQuery(sql);
...
} catch (ClassNotFoundException | SQLException | URISyntaxException e) {
e.printStackTrace();
}
}
}
How can I point CsvJdbc to my csv file contained within a .jar?
There simply is no directory of a package within the JAR. It works in IDE because your class is not yet packaged in a JAR file and resides in some directory. But this is not the case with JARs.
So if some of the libraries you use require a directory with a file in it, you can't generally achieve this with classpath resources. One of the options would be to create a copy of your resource as a file in a temporary directory.
Alternatively you may want to study the CsvJDBC documentation closer:
To read data that is either held inside the Java application (for example, in a JAR file) or accessed remotely (for example, using HTTP requests), create a Java class that implements the interface org.relique.io.TableReader and give this class name in the connection URL. CsvJdbc then creates an instance of this class and calls the getReader method to obtain a java.io.Reader for each database table being read.
So you should be able to solve this for CsvJDBC without temporary directories.

Want to delete existing document from folder and database values from table using transaction in hibernate query

I have an application with document uploading.After uploading the document,the document path is newly created and the document is saved within the file path.At the same time the document path and related values are saved with in the database table.In my application after uploading,there is a button to delete the unwanted document.Sometimes the document deletion operation is not properly work.So there is a wastage of memory will occur.I want to avoid the situation by using transaction statement.I don't know how to use the hibernate transaction to my work.Is this possible? Please help me to do the work successfully(I am using spring with hibernate integration and postgresql)
Thank you
In controller
int supDocId=1102;
String docPath=D:/;
String filePath=docPath+supDocId+".pdf";
File file=new File(filePath);
boolean isDelete = servicesService.deleteDocument(supDocId);
if(isDelete)
{
if(file.exists())
{
file.delete();
}
alertMsg = "The file is deleted sucessfully";
}
else{
alertMsg = "Deletion Failed.!!! File is under processing..";
}
In service class
public boolean deleteDocument(int supDocId){
return servicesDAO.deleteDocument(supDocId);
}
In servicesDAO class
public boolean deleteDocument(int supDocId){
int deleteStatus=0;
try {
String deleteQuery = "DELETE FROM tablename WHERE attch_doc_id='"+supDocId+"'";
Query deleteQ = session.createSQLQuery(deleteQuery);
deleteStatus = deleteQ.executeUpdate();
if(deleteStatus>0){
return deleteStatus;
}
} catch (Exception e) {
e.printStackTrace();
}
return deleteStatus;
}
I want to work the two operations(document and database value deletion) within the DAO class using transaction statement.
If DB transaction fails - you will have problem not only with deleted files, but also with uploaded new files.
In most cases file system does not supports transaction so I don't think bullet proof solution can be achieved using XA (distributed transactions using the JTA) or similar approach.
Quite strait forward solution I am using in some of my projects:
Files in file system are created before DB commit (but preferably after hibernate flush).
On file delete operation, reference to file is deleted from DB, but not from file system.
Asynchronous process periodically scans all files in file system and deletes files with no references from DB.
If you have big number of files some optimization can be necessary to prevent always scan all files. For example:
Put new files to folder with name "current date", so only part of files can be checked for unsuccessful transactions involving uploaded new files.
On file delete operation insert new record to table "deleted_files" with reference to file that should be deleted.
Create asynchronous process to periodically scans table "deleted_files", which deletes physical file and if deletion is successful (or file already is missing) removes record from table "deleted_files" and commits transaction.
You shouldn't use +supDocId+ Replace that with ? instead or you would be leaving yourself vulnerable to Sql Injection.
And deleteQ.Execute();is what you want to be doing not an update because you want to be checking boolean true or false if something is deleted.

Add and use files in JAVA Jar as they would be in the folder

I have JAVA project which contains some *.sql files and on deploy if there is no database cleated yet I can run some classes which applies those *.sql files on database.
But I have to make JAVA Jar file out of it in order to deploy. I do know how to run any class from jar, but how to add and access my *.sql in the Jar if I do not want extract the files.
The *sql files that I need is being used the following way:
mysql -uroot -ppassword < databaseStructure.sql
that creates me database. somehow I need access that file out of jar when necessary.
InputStream stream = YourClass.class.getResourceAsStream("/" + pathToYourFile);
Example:
You have a file insertSomething.sql in your jar.
public static String getResourceContent(
final String path) throws IOException {
InputStream stream = YourClass.class.getResourceAsStream("/" + path);
if (stream != null) {
return IOUtils.toString(stream);
}
}
Now you can get the content:
String content = getResourceContent("insertSomething.sql");
You can get an InputStream from files in your classpath. I'm not sure if that does what you need, exactly.
See this previous SO article on the topic: Different ways of loading a file as an InputStream

Property file not reflecting the modified changes using Apache Commons Configuration

I am trying to explore Apache commons configuration to dynamically load the property file and do modification in the file and save it.
I wrote a demo code for the same.
Code Snippet
package ABC;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
public class Prop {
public static void main(String[] args)
{
try {
URL propertiesURL = Prop.class.getResource("/d1.properties");
if (propertiesURL == null) {
System.out.println("null");
}
String absolutePath=propertiesURL.getPath();
PropertiesConfiguration pc = new PropertiesConfiguration(absolutePath);
pc.setReloadingStrategy(new FileChangedReloadingStrategy());
String s=(String)pc.getProperty("key_account_sales");
System.out.println("s is " + s);
pc.setAutoSave(true);
pc.setProperty("key_account_sales", "Dummy");
pc.save();
System.out.println("Modified as well");
String sa=(String)pc.getProperty("key_account_sales");
System.out.println("s is " + sa);
}catch(ConfigurationException ce)
{
ce.printStackTrace();
}
}
}
Although when I run the code multiple times, the updated value for the property is being properly shown but the changes are not seen in the Property file.
I tried refreshing the entire workspace and the project but still the property file shows the previous entry whereas this code displays the updated entry in console.
Why my property file is not getting updated?
Well I noticed that a new file with same name was formed inside bin
directory of my IDE workspace. This new file contains the required
changes.
However I still want that the old file should be updated with the new
value and instead of creating a new file, it should update in the old
file itself.
My property file is located inside a Web Application package say
Dem1
by the name of
Prop1.prop
I want to read this property file from in another class say
Reading.java
located inside another package
Dem2
, do changes in this same property file and show it to another user. It is a web application being deployed on an application server.
Even after using the absolute path in a simple file (main function) it is not reflecting the changes in the same file but updating it in new file.
I am doing a very slight mistake but can someone please help.
Using absolute path I am not able to make changes in the same property file in normal main method also. Please suggest.
New file in bin directory is created instead of updating the same file
in src folder.
You should be able to solve this using absolute paths. The PropertiesConfiguration class is finding your properties file somewhere on the classpath and only knows to write back to "d1.properties"; hence you have a file appearing in your bin directory.
The absolute path can be obtained by querying resources on the classpath. Something like the following:
URL propertiesURL = Prop.class.getResource("/d1.properties");
if (propertiesURL == null) {
// uh-oh...
}
String absolutePath = propertiesURL.getPath();
// Now use absolutePath

Understanding Simple XML Parser - New File Output - Java

I am trying to learn how to use the Simple XML Framework as detailed in this thread : Best practices for parsing XML.
I am using the following code :
public class SimpleXMLParserActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
Serializer serializer = new Persister();
Example example = new Example("Example message", 123);
File result = new File("example.xml");
try {
Log.d("Start", "Starting Serializer");
serializer.write(example, result);
} catch (Exception e) {
// TODO Auto-generated catch block
Log.d("Self", "Error");
e.printStackTrace();
}
}
}
I am having a problem understanding the line
File result = new File("example.xml");
1) Does this line create a new file in my app called example.xml ? If so where is this file located.
2) Or does this line look for an existing file called example.xml and then add to it ? If so where should the example.xml file be placed in my app bundle so that it can be found. I do notice at the moment I am getting an error message :
java.io.FileNotFoundException: /example.xml (Read-only file system)
Thank you.
File result = new File("example.xml")
This line will just store the filename "example.xml" in a new File object. There is no check if that file actually exists and it does not try to create it either.
A file without specifying an absolute path (starting with / like new File("/sdcard/example.xml")) is considered to be in the current working directory which I guess is / for Android apps (-> /example.xml (Read-only file system))
I guess serializer.write(example, result); tries to create the actual file for your but fails since you can't write to '/'.
You have to specify a path for that file. There are several places you can store files, e.g.
Context#getFilesDir() will give you a place in your app's home directory (/data/data/your.package/files/) where only you can read / write - without extra permission.
Environment#getExternalStorageDirectory() will give you the general primary storage thing (might be /sdcard/ - but that's very different for devices). To write here you'll need the WRITE_EXTERNAL_STORAGE permission.
there are more places available in Environment that are more specialized. E.g. for media files, downloads, caching, etc.
there is also Context#getExternalFilesDir() for app private (big) files you want to store on the external storage (something like /sdcard/Android/data/your.package/)
to fix your code you could do
File result = new File(Environment.getExternalStorageDirectory(), "example.xml");
Edit: either use the provided mechanisms to get an existing directory (preferred but you are limited to the folders you are supposed to use):
// via File - /data/data/your.package/app_assets/example.xml
File outputFile = new File(getDir("assets", Context.MODE_PRIVATE), "example.xml");
serializer.write(outputFile, result);
// via FileOutputStream - /data/data/your.package/files/example.xml
FileOutputStream outputStream = openFileOutput("example.xml", Context.MODE_PRIVATE);
serializer.write(outputStream, result);
or you may need to create the directories yourself (hackish way to get your app dir but it should work):
File outputFile = new File(new File(getFilesDir().getParentFile(), "assets"), "example.xml");
outputFile.mkdirs();
serializer.write(outputFile, result);
Try to avoid specifying full paths like "/data/data/com.simpletest.test/assets/example.xml" since they might be different on other devices / Android versions. Even the / is not guaranteed to be /. It's safer to use File.separatorChar instead if you have to.
2 solutions to do it cleanly :
use openFileOutput to write a private file in the application private directory (which could be located in the internal memory or the external storage if the app was moved there). See here for a snippet
or use the File constructor to create the File anywhere your app has write access. This is if you want to store the file on the SDCard for example. Instantiating a file doesn't create it on the file system, unless you start writiung to it (with FileOutputStream for example)
I'd recommend approach 1, it's better for users because these files get erased when your app is uninstalled. If the file is large, then using the External Storage is probably better.
What I read on the Android pages, I see it creates a file with that name:
File constructor
I think it writes it to the /data/data/packagname directory
edit: the 'packagename' was not shown in the tekst above. I put it between brackets. :s
Try saving to /sdcard/example.xml.

Categories

Resources