Java Object Serialization and Deserialization In MySQL Database

In my previous article, I showed how any java object can be serialized to a file system, and how to read the object once it has been written to the file.

In this article, I am providing you a working code that I wrote and tested which stores java object into the database. I tested this coder the mysql database. There is no reason why it should not work for other databases.

The following is a summary of what is covered in this example:

  • Query to create tables in database for the purpose of storing java objects.
  • Query to write java objects to the database
  • Query to read java objects from the database
  • Basic mechanism of connecting to the database from Java Application
  • How to write Java Object to the database using prepared statements
  • How to read the Java Objects from the database using prepared statements.
  • You will see that the objects will be stored in database in the form of BLOB data type.

The following is a working code fully compiled and tested. Make sure to change the database credentials, url and name to suit your environment.

package com.kushal.serialization
/**SQL to create MySQL Table For Object Storing**/

/*CREATE TABLE javaobjects (
 objectid INT AUTO_INCREMENT,
 object_name varchar(100),
 object_value BLOB,
 primary key (objectid));
 */

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ObjectSerializationToMySQL {
	static final String SQL_TO_WRITE_OBJECT = "INSERT INTO JAVAOBJECTS(OBJECT_NAME, OBJECT_VALUE) VALUES (?, ?)";
	static final String SQL_TO_READ_OBJECT = "SELECT OBJECT_VALUE FROM JAVAOBJECTS WHERE OBJECTID = ?";

	static String driver = "com.mysql.jdbc.Driver";
	static String url = "jdbc:mysql://localhost/generaldb";
	static String username = "root";
	static String password = "root";

	/**
	 * This class will create and return a database connection.
	 */
	public static Connection getConnection() throws Exception {
		Class.forName(driver);
		Connection conn = DriverManager.getConnection(url, username, password);
		return conn;
	}

	/**
	 * This method will write a java object
	 * to the database
	 * Parameters: connection object and object to be serialized
	 */
	public static long writeJavaObject(Connection conn, Object object)
			throws Exception {
		String className = object.getClass().getName();
		PreparedStatement pstmt = conn.prepareStatement(SQL_TO_WRITE_OBJECT);
		pstmt.setString(1, className);
		pstmt.setObject(2, object);
		pstmt.executeUpdate();
		ResultSet rs = pstmt.getGeneratedKeys();
		int id = -1;
		if (rs.next()) {
			id = rs.getInt(1);
		}
		rs.close();
		pstmt.close();
		System.out.println("Serialization Successful."+
						   "Serialized Class: "+ className);
		return id;
	}

	/**
	 * This class will de-serialize a java object from the database
	 */
	public static Object readJavaObject(Connection conn, long id)
			throws Exception {
		PreparedStatement pstmt = conn.prepareStatement(SQL_TO_READ_OBJECT);
		pstmt.setLong(1, id);
		ResultSet rs = pstmt.executeQuery();
		rs.next();
		byte[] buf = rs.getBytes("object_value");
		ObjectInputStream objectIn = null;
		if (buf != null)
			objectIn = new ObjectInputStream(new ByteArrayInputStream(buf));
		Object object = objectIn.readObject();
		String className = object.getClass().getName();
		rs.close();
		pstmt.close();
		System.out.println("Deserialization Successful."+
							"nDeserialized Class: "+ className);
		return object;
	}

	/**
	 * Testing the serialization and deserialization feature.
	 */

	public static void main(String args[]) throws Exception {
		Connection conn = null;
		try {
			/**Creating DB Connection**/
			conn = getConnection();
			conn.setAutoCommit(false);
			/**Creating Test object to Serialize**/
			MyObjectToSerialize obj = new MyObjectToSerialize("Roberto",
					"Armando", 35);
			/**
			 * Serializing the object and getting the database id,
			 * which is nothing but an autogenerated key
			 */
			long objectID = writeJavaObject(conn, obj);
			conn.commit();
			System.out.println("Serialized object ID" + objectID);
			/**
			 * Reading the object from database.
			 * This object is just serialized into database above.
			 */

			MyObjectToSerialize objFromDatabase = (MyObjectToSerialize) readJavaObject(
					conn, objectID);
			System.out.println("After Deserialization:");
			System.out.println("Object Value: " + objFromDatabase);
			System.out.println("Class: " + objFromDatabase.getClass().getName());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			/**Closing the database connection**/
			conn.close();
		}
	}
}

The following is the class which is serialized/de-serialized using the class above. Please note that any class which has to be serialized needs to implement Serialization interface.  Please refer to my previous article for further details

package com.kushal.serialization;
/**
 * @author Kushal Paudyal
 * www.sanjaal.com/java
 * Last Modified 09/01/2009 mm-dd-yyyy
 */
import java.io.Serializable;
public class MyObjectToSerialize implements Serializable {

	private String firstName;
	private String lastName;
	private int age;
	public MyObjectToSerialize(String firstName, String lastName, int age) {
		this.firstName = firstName;
		this.lastName = lastName;
		this.age = age;
	}
	public String toString() {
		return firstName + " " + lastName + ", " + age;
	}
}

===========
Output of this program:
Serialization Successful.Serialized Class: com.kushal.serialization.MyObjectToSerialize
Serialized object ID6
Deserialization Successful.
Deserialized Class: com.kushal.serialization.MyObjectToSerialize
After Deserialization:
Object Value: Roberto Armando, 35
Class: com.kushal.serialization.MyObjectToSerialize


Content of the database after running the program:

How To Set Conditional Debug Breakpoints in Eclipse or IBM RAD?

Developers and Production Support Analysts will, in their lifetime, spend a lot of time debugging, specially if the applicaiton is complex and they have no idea on what’s going on. I mentioned Production Support Analysts because they are the ones in most companies analyzing and fixing the defects in production environments. Developing the new features probably does not need you as much to debug as it needs for maintenance work, specially if you are trying to understand what’s going on and what is the flow.

There are many occasions you don’t want to debug every steps. For example, if there is a for loop that loops for a 1000 times and that you know it fails on the 100th step or are intersted to see what’s going on somewhere around that, would it make sense to go through the 99 steps of debugging before hitting the 100th one? It certainly does not make sense to me unless you have a lot of time to hit those debug short cuts (I love those F5,F6,F7,F8 shortcut keys in Eclipse and IBM RAD by the way).

So what can you do about it? Well the IDEs like Eclipse or IBM RAD offer you a way to set conditional breakpoints – the IDE will stop at the breakpoint you set only when certain conditons are met.

The following is some piece of code with a for-loop. Let’s say we are interested to look at the value of the variable ‘random’ when the value of i is 100.

package com.kushal.tools.published;
/**
 * @author Kushal Paudyal
 * www.sanjaal.com/java
 * www.icodejava.com
 * 
 * Written to be used in a tutorial to show how to do 
 * conditional break points in eclipse
 */

public class ConditionalBreakPointEclipse {

    public static void main(String args[]) {

        doSomeStuff();
    }

    /** Just outputting some random numbers. We would like to
     * add a conditional breakpoint when the value of i is 100.
     */
    public static void doSomeStuff() {

        for (int i = 0; i <= 1000; i++) {

            double random = i * Math.random();

            System.out.println(i + " - Random - " + random);
        }
    }

}

The first step is to set a breakpoint where it says

double random = i * Math.random();

Here is a screenshot for that.

Eclipse - Putting a breakpoint

The second step is to right click on the breakpoint and choose ‘Breakpoint Properties…’.

Eclipse - right click on the breakpoint

On the third step, enable the checkbox ‘Conditional’. The text area underneath the checkbox will be enabled and that is a place where you can put your conditions. In my case, I simply typed in i==100 because I wanted to stop when the value of i is 100.

Eclipse - Adding the conditional in the Line Breakpoint Properties

Now close the window and run the application in debug mode. You will see that after the value of i reaches 100 and when the statement where we put the breakpoint is reached, the IDE will stop for you to evaluate the variables at that point. Isn’t that neat? Once you hit F7, the program should continue without another stop at the breakpoint.

Eclipse - Debugging with conditional breakpoint

Compare this to not having a conditional breakpoint. You would have to step through 99 times before it reached your desired value of i and to finish debugging the program, you would have to hit F7 for another 900 times (or just stop debugging)!!

You are going to appreciate that IDEs provide this great feature.

Rotating An Image In Java Graphics 2D By Specified Degree

The following java example will read an input image from the file system, and then it will rotate the image with the angle in degrees provided in the parameter while calling rotateMyImage method from the main method. It will then save the rotated image back to the file system as a new image file.

package com.kushal.graphics;
/**
 * @Author Kushal Paudyal
 * www.sanjaal.com/java
 * Last Modified On 2009-10-08
 *
 * Using Graphics 2D To Rotate An Image
 */
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class ImageRotator {
public static void main (String args [])
{
String inputFileLocation="C:/temp/myImage02.jpg";
String outputFileLocation ="C:/temp/myImage-Rotated02.jpg";;
double angleOfRotation=10.0;

System.out.println("Reading Original File : "+inputFileLocation);

BufferedImage originalImage=readImage(inputFileLocation);

System.out.println("...Donen");

System.out.println("Rotating the original Image By: "+angleOfRotation+" degrees");
BufferedImage processedImage=rotateMyImage(originalImage, angleOfRotation);
System.out.println("...Donen");

System.out.println("Writing the rotated image to: "+outputFileLocation);
writeImage(processedImage, outputFileLocation, "jpg");
System.out.println("...Done");
}

public static BufferedImage rotateMyImage(BufferedImage img, double angle) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage dimg =new BufferedImage(w, h, img.getType());
Graphics2D g = dimg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, // Anti-alias!
RenderingHints.VALUE_ANTIALIAS_ON);

g.rotate(Math.toRadians(angle), w/2, h/2);

g.drawImage(img, null, 0, 0);
return dimg;
}

/**
* This method reads an image from the file
* @param fileLocation -- > eg. "C:/testImage.jpg"
* @return BufferedImage of the file read
*/
public static BufferedImage readImage(String fileLocation) {
BufferedImage img = null;
try {
img = ImageIO.read(new File(fileLocation));
} catch (IOException e) {
e.printStackTrace();
}
return img;
}

/**
* This method writes a buffered image to a file
* @param img -- > BufferedImage
* @param fileLocation --> e.g. "C:/testImage.jpg"
* @param extension --> e.g. "jpg","gif","png"
*/
public static void writeImage(BufferedImage img, String fileLocation,
String extension) {
try {
BufferedImage bi = img;
File outputfile = new File(fileLocation);
ImageIO.write(bi, extension, outputfile);
} catch (IOException e) {
e.printStackTrace();
}
}

/*
* SANJAAL CORPS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SANJAAL CORPS SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
* THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
* CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
* PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
* NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
* SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
* SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
* PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). SANJAAL CORPS
* SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
* HIGH RISK ACTIVITIES.
*/
}


The output of this program:

Reading Original File : C:/temp/myImage02.jpg
...Done

Rotating the original Image By: 10.0 degrees
...Done

Writing the rotated image to: C:/temp/myImage-Rotated02.jpg
...Done

Original Image File:

Image Rotated By The Java Code Above: