java read arrayList<Integer> - objectInputStream EOFEXception - java

Hi i am trying to read an ArrayList of Integer and get EOFException.
i have a ArrayList of Question which is serialized and i do the same thing for reading it no problem, but with ArrayList Integer dont work.
i write the two ArrayList like so: (im ommiting all the other fields that are not relevant)
String sqlQuery = "insert into test values (?,?,?,?,?,?,?,?,?)";
PreparedStatement pst = null;
try {
if (DBConnector.myConn != null) {
pst = DBConnector.myConn.prepareStatement(sqlQuery);
// serialize object
Blob questionsBlob = DBConnector.myConn.createBlob();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(t.getQuestions());
oos.close();
Blob pointsBlob = DBConnector.myConn.createBlob();
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
ObjectOutputStream oos2 = new ObjectOutputStream(baos2);
oos.writeObject(t.getPointsPerQuestion());
oos2.close();
// store in byte array
byte[] questionsAsByte = baos.toByteArray();
byte[] pointsAsByte = baos2.toByteArray();
// fill blob object with byte array
questionsBlob.setBytes(1, questionsAsByte);
pointsBlob.setBytes(1, pointsAsByte);
pst.setBlob(3, questionsBlob);
pst.setBlob(4, pointsBlob);
pst.executeUpdate();
and read the objects:
String sqlQuery = "select * from test where teacherUsername = \"" + username + "\";";
ArrayList<Test> arr = new ArrayList<Test>();
ArrayList<Question> questions;
ArrayList<Integer> points;
try {
if (DBConnector.myConn != null) {
Statement st = DBConnector.myConn.createStatement();
ResultSet rs = st.executeQuery(sqlQuery);
while (rs.next()) {
questions = new ArrayList<>();
points = new ArrayList<>();
Blob questionsBlob = rs.getBlob(3);
BufferedInputStream bis = new BufferedInputStream(questionsBlob.getBinaryStream());
ObjectInputStream ois = new ObjectInputStream(bis);
questions = (ArrayList<Question>) ois.readObject();
System.out.println(questions);
Blob qPointsBlob = rs.getBlob(4);
BufferedInputStream bis1 = new BufferedInputStream(qPointsBlob.getBinaryStream());
ObjectInputStream ois1 = new ObjectInputStream(bis1);
try {
points = (ArrayList<Integer>) ois1.readObject(); // PROBLEM HERE
}catch(EOFException e) {
System.out.println(points);
}
when i try to read the data - it works with the ArrayList of Question and really shows me the questions, but with the ArrayList of Integer it gives me the EOFException.
any ideas ?

Related

Read java.io.File from mysql blob

I have the below code which stores a List to File and then to a mysql blob column. Is it possible to recover that List from the database?
ArrayList<String> myList = new ArrayList<String>();
File tempFile = File.createTempFile("myFile.temp");
tempFile.deleteOnExit();
FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeUnshared(myList);
objectOutputStream.close();
String trailQuery = "INSERT INTO table (tempFile) VALUES (?)";
PreparedStatement preparedStatement = connection.prepareStatement(trailQuery);
preparedStatement.setObject(1, tempFile);
I tried to read that but I get a FileNotFoundException
if (resultSet.next()) {
InputStream fileInputStream = resultSet.getBinaryStream("tempFile");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
File inner = (File) objectInputStream.readObject();
FileInputStream fileInputStreamInner = new FileInputStream(inner);
ObjectInputStream objectInputStreamInner = new ObjectInputStream(fileInputStreamInner);
ArrayList<String> myList = (ArrayList<String>) objectInputStreamInner.readObject();
System.out.println(myList.size());
}
Exception
java.io.FileNotFoundException: \tmp\myFile.1708309680603860570.temp (The system cannot find the path specified)
As #EJP mentioned a java.io.File is nothing more than a holder for a filename... had wrong understanding - so none of the contents of the files are there....

Hibernate convert existing Integer[] to String[] (bytea) in Postgres database

I'm using Spring, Hibernate and Postgres.
In one of my model class I have:
#Entity
class SomeData {
private Long dataId;
private String name;
private Integer[] data;
}
It is already used and I have data in database in above format.
"data" field is a bytea (visible in phppgadmin) type, one of the example values saved in db is:
��ur[Ljava.lang.Integer;������xpsr...
Problem is that now I need to change model to
String[] data;
But when I do that Hibernate can't read those data because it has type Integer.
My question - is it possible to convert somehow these Integer array objects to String array objects? Using some db tool, sql query or Hibernate?
You need to write a conversion algorithm to run once. Something like:
Connection c = ((SessionImplementor)entitymanager).connection();
boolean oldstate = c.getAutoCommit();
c.setAutoCommit(false);
Statement s = c.createStatement();
PreparedStatement ps = c.prepareStatement("UPDATE my_table SET data = ? WHERE id = ?");
ResultSet rs = s.executeQuery("SELECT id, data FROM my_table");
ByteArrayInputStream bais;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectInputStream ois;
ObjectOutputStream oos = new ObjectOutputStream(baos);
while (rs.next()) {
long id = rs.getLong(1);
byte[] bdata = rs.getBytes(2);
bais = new ByteArrayInputStream(bdata);
ois = new ObjectInputStream(bais);
Integer[] olddata = (Integer[]) ois.readObject();
String[] newdata = new String[olddata.length];
for (int i = 0; i < olddata.length; i++) {
Integer din = olddata[i];
String dout = null;
if (din != null) {
dout = din.toString();
}
newdata[i] = dout;
}
oos.writeObject(newdata);
oos.flush();
ps.setLong(1, id);
ps.setBytes(2, baos.toByteArray());
baos.reset();
}
c.commit();
c.setAutoCommit(oldstate);
If you want to do it through Hibernate, you'd need a secondary column, or you'd have to change it to Object[], run the conversion, then change it to String[], but that's not convenient for update on production, nor is it efficient, as you'd go through a lot of layers of validations and conversions inside Hibernate.
However, if you choose to use array types inside the database itself, I have a standalone module currently proposed that allows for it https://github.com/hibernate/hibernate-orm/pull/1499 . We don't have test-cases that don't work with it, but if you can find any that need fixing, that would help with getting it approved.

Convert ArrayList to byte array

I have a code where I am converting array list to byte array and then saving that byte array as a BLOB in MySQL database. Below is code:-
Object temp = attributes.get(columnName);
if (temp instanceof List && temp != null) {
List extraAttributes = (ArrayList) temp;
resultStmt.setBytes(currentIndex, createByteArray(extraAttributes));
The method createByteArray is defined as below:
private byte [] createByteArray( Object obj)
{
byte [] bArray = null;
try
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream objOstream = new ObjectOutputStream(baos);
objOstream.writeObject(obj);
bArray = baos.toByteArray();
}
catch (Exception e)
{
TraceDbLog.writeError("Problem in createByteArray", e);
}
return bArray;
}
Well the above code was written earlier for writing HashMap to BLOB i am using same for converting ArrayList if HashMap to BLOB.
The problem which is occurring in read code when i am reading the blob.
private Object readBytes (ResultSet rs, String columnName)
throws SQLException
{
ObjectInputStream ois = null;
byte [] newArray;
Object obj = null;
try
{
newArray = rs.getBytes(columnName);
ois = new ObjectInputStream (new ByteArrayInputStream(newArray));
obj = ois.readObject ();
}
In the read part the object is not coming as arrayList of hasMap and in debug perspective in eclipse eclipse is also not able to inspect the object which is coming.
I have also tried typecasting the object to List but still no success in getting the right response.
Please tell me whether there is any flaw in reading/writing the above BLOB.
I have added sample coding for convert ArrayList to byte[].
One reasonable way would be to use UTF-8 encoding like DataOutputStream does for each string in the list. For a string it writes 2 bytes for the length of the UTF-8 encoding followed by the UTF-8 bytes.
This would be portable if you're not using Java on the other end. Here's an example of encoding and decoding an ArrayList:
// example input list
List<String> list = new ArrayList<String>();
list.add("foo");
list.add("bar");
list.add("baz");
// write to byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(baos);
for (String element : list) {
out.writeUTF(element);
}
byte[] bytes = baos.toByteArray();
// read from byte array
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
DataInputStream in = new DataInputStream(bais);
while (in.available() > 0) {
String element = in.readUTF();
System.out.println(element);
}
The easiest way is to convert it to json string and then to bytes
Gson gson = new Gson();
Type type = new TypeToken<List<Alarm>>() {}.getType();
String json = gson.toJson(list, type);
byte[] bytes = json.getBytes();

File writing with blob data

I am reading the blob data from Oracle database & writing it to a text file. I have two column in my database called Number & system. I have 100 counts in my table. But only the last row is writing in my text row. below is the code I have tried.
rs =stmt.executeQuery("select Number, system from system");
Blob lob = null;
while (rs.next()) {
String RECID = rs.getString(1);
System.out.println("Number"+ Number);
lob=rs.getBlob("system");
byte[] bdata = lob.getBytes(1, (int) lob.length());
String text = new String(bdata);
System.out.println("text"+ text);
System.out.println("rs value"+ lob);
String test=null;
test=RECID+":"+text;
FileOutputStream fos = new FileOutputStream("C:/DataRead/system.txt");
DataOutputStream dos = new DataOutputStream(fos);
dos.writeBytes(test);
dos.close();
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
In text file i am getting 100th record only other 99 rows are not writing.
You are replacing existing text each time in your while loop.
Try this:
FileOutputStream fos = new FileOutputStream("C:/DataRead/system.txt");
DataOutputStream dos = new DataOutputStream(fos);
while (rs.next()) {
String RECID = rs.getString(1);
System.out.println("Number"+ Number);
lob=rs.getBlob("system");
byte[] bdata = lob.getBytes(1, (int) lob.length());
String text = new String(bdata);
System.out.println("text"+ text);
System.out.println("rs value"+ lob);
String test=null;
test=RECID+":"+text;
dos.writeBytes(test+"\n");
}
dos.close();
Replace the line in your code
FileOutputStream fos = new FileOutputStream("C:/DataRead/system.txt");
With:
FileOutputStream fos = new FileOutputStream("C:/DataRead/system.txt", true);

Convert byte [] to ArrayList<Object>

I have a byte[] that i obtained using Object ArrayList<Obj>
Can anyone tell me how to convert my byte[] to Object ArrayList?
Coveting ArrayList like this:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = null;
oos = new ObjectOutputStream(bos);
oos.writeObject(mArrayList);//mArrayList is the array to convert
byte[] buff = bos.toByteArray();
Now you've given us the information about how you did the conversion one way... you need:
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
try {
#SuppressWarnings("unchecked")
ArrayList<Object> list = (ArrayList<Object>) ois.readObject();
...
} finally {
ois.close();
}
I'm going to go with the obvious answer here...
for(byte b : bytearray) {
arraylist.add(new Byte(b));
}

Categories

Resources