Skip to main content
added 234 characters in body
Source Link

And another thing I don't understand, if I compare a string with a clob (identical values), the code that compares the clob is used, whereas instanceof is not supposed to be identical...! Here

What I expect is my code: when I compare 2 differents clobs, comparison as objects is false, as string (simplified for exampletoString output): is false, it detects that objects are instanceof clobs, so convert them as string, and then compare string values.

Here is my code (simplified for example):

import java.io.*;
import java.sql.*;
import javax.sql.rowset.serial.*;

public class TestClob {
    
    public static void main(String[] args) throws SerialException, SQLException {
        boolean result;
        Object text1="abcdef", text2="abcdef";
        Clob clob1 = new SerialClob(((String) text1).toCharArray());
        Clob clob2 = new SerialClob(((String) text2).toCharArray());
        Clob clob3 = new SerialClob("abcdefg".toCharArray());

        System.out.println("TEST 1, basic string comparison");
        System.out.println("-------------------------------");
        result = haveSameValue(text1, text2);
        System.out.println("result: "+result);
        
        System.out.println("\nTEST 2, clob vs string");
        System.out.println("----------------------");
        result = haveSameValue(clob1, text1);
        System.out.println("result: "+result);
        
        System.out.println("\nTEST 3, different clobs objects but same value");
        System.out.println("----------------------------------------------");
        result = haveSameValue(clob1, clob2);
        System.out.println("result: "+result);
        
        System.out.println("\nTEST 4, different clobs");
        System.out.println("-----------------------");
        result = haveSameValue(clob1, clob3);
        System.out.println("result: "+result);
    } 
    
    public static boolean haveSameValue(Object obj1, Object obj2) {
        String sObj1, sObj2, sObj1Class, sObj2Class;
        boolean result = true;false;

        if (obj1!=null && obj2!=null) {
            sObj1Class = obj1.getClass().toString().toLowerCase();
            sObj2Class = obj2.getClass().toString().toLowerCase();
            System.out.println("  Objects class : sObj1Class="+sObj1Class+", sObj2Class="+sObj2Class);

            System.out.println("  OBJECT : obj1="+obj1+", obj2="+obj2+", => equal as object? "+obj1.equals(obj2));
            
            if (!obj1.equals(obj2)) {
                sObj1=obj1.toString();
                sObj2=obj2.toString();
                System.out.println("  STRING : sObj1="+sObj1+", sObj2="+sObj2+", => equal as string? "+sObj1.equals(sObj2));
                
                if (!sObj1.equals(sObj2)) {                 
                    if (obj1 instanceof java.sql.Clob || obj2 instanceof java.sql.Clob) {
                        sObj1 = ClobToString(obj1);
                        sObj2 = ClobToString(obj2);
                        System.out.println("  CLOB : sObj1="+sObj1+", sObj2="+sObj2+" => equal as clob? "+sObj1.equals(sObj2));
                        result = sObj1.equals(sObj2);
                    }
                    
                    // other comparisons (as a date, timestamp, number...)
                }
            }
        }
        
        return result;
    }
    
    public static String ClobToString(Object object) {
        if (object==null) {
            return null;
        }
        else if (object instanceof java.sql.Clob) {
            StringBuilder sb = new StringBuilder();
            try {
                Reader reader = ((java.sql.Clob) object).getCharacterStream();
                BufferedReader br = new BufferedReader(reader);

                String line;
                while(null != (line = br.readLine())) {
                    sb.append(line);
                }
                br.close();
                return sb.toString();
            }
            catch (Exception e) {
                System.out.println("error : "+e.getMessage());
                return object.toString();
            }
        }
        else {
            return object.toString();
        }
    }
}

And another thing I don't understand, if I compare a string with a clob (identical values), the code that compares the clob is used, whereas instanceof is not supposed to be identical...! Here is my code (simplified for example):

import java.io.*;
import java.sql.*;
import javax.sql.rowset.serial.*;

public class TestClob {
    
    public static void main(String[] args) throws SerialException, SQLException {
        boolean result;
        Object text1="abcdef", text2="abcdef";
        Clob clob1 = new SerialClob(((String) text1).toCharArray());
        Clob clob2 = new SerialClob(((String) text2).toCharArray());
        Clob clob3 = new SerialClob("abcdefg".toCharArray());

        System.out.println("TEST 1, basic string comparison");
        System.out.println("-------------------------------");
        result = haveSameValue(text1, text2);
        System.out.println("result: "+result);
        
        System.out.println("\nTEST 2, clob vs string");
        System.out.println("----------------------");
        result = haveSameValue(clob1, text1);
        System.out.println("result: "+result);
        
        System.out.println("\nTEST 3, different clobs objects but same value");
        System.out.println("----------------------------------------------");
        result = haveSameValue(clob1, clob2);
        System.out.println("result: "+result);
        
        System.out.println("\nTEST 4, different clobs");
        System.out.println("-----------------------");
        result = haveSameValue(clob1, clob3);
        System.out.println("result: "+result);
    } 
    
    public static boolean haveSameValue(Object obj1, Object obj2) {
        String sObj1, sObj2, sObj1Class, sObj2Class;
        boolean result = true;

        if (obj1!=null && obj2!=null) {
            sObj1Class = obj1.getClass().toString().toLowerCase();
            sObj2Class = obj2.getClass().toString().toLowerCase();
            System.out.println("  Objects class : sObj1Class="+sObj1Class+", sObj2Class="+sObj2Class);

            System.out.println("  OBJECT : obj1="+obj1+", obj2="+obj2+", => equal as object? "+obj1.equals(obj2));
            
            if (!obj1.equals(obj2)) {
                sObj1=obj1.toString();
                sObj2=obj2.toString();
                System.out.println("  STRING : sObj1="+sObj1+", sObj2="+sObj2+", => equal as string? "+sObj1.equals(sObj2));
                
                if (!sObj1.equals(sObj2)) {                 
                    if (obj1 instanceof java.sql.Clob || obj2 instanceof java.sql.Clob) {
                        sObj1 = ClobToString(obj1);
                        sObj2 = ClobToString(obj2);
                        System.out.println("  CLOB : sObj1="+sObj1+", sObj2="+sObj2+" => equal as clob? "+sObj1.equals(sObj2));
                        result = sObj1.equals(sObj2);
                    }
                    
                    // other comparisons (as a date, timestamp, number...)
                }
            }
        }
        
        return result;
    }
    
    public static String ClobToString(Object object) {
        if (object==null) {
            return null;
        }
        else if (object instanceof java.sql.Clob) {
            StringBuilder sb = new StringBuilder();
            try {
                Reader reader = ((java.sql.Clob) object).getCharacterStream();
                BufferedReader br = new BufferedReader(reader);

                String line;
                while(null != (line = br.readLine())) {
                    sb.append(line);
                }
                br.close();
                return sb.toString();
            }
            catch (Exception e) {
                System.out.println("error : "+e.getMessage());
                return object.toString();
            }
        }
        else {
            return object.toString();
        }
    }
}

And another thing I don't understand, if I compare a string with a clob (identical values), the code that compares the clob is used, whereas instanceof is not supposed to be identical...!

What I expect is: when I compare 2 differents clobs, comparison as objects is false, as string (toString output) is false, it detects that objects are instanceof clobs, so convert them as string, and then compare string values.

Here is my code (simplified for example):

import java.io.*;
import java.sql.*;
import javax.sql.rowset.serial.*;

public class TestClob {
    
    public static void main(String[] args) throws SerialException, SQLException {
        boolean result;
        Object text1="abcdef", text2="abcdef";
        Clob clob1 = new SerialClob(((String) text1).toCharArray());
        Clob clob2 = new SerialClob(((String) text2).toCharArray());
        Clob clob3 = new SerialClob("abcdefg".toCharArray());

        System.out.println("TEST 1, basic string comparison");
        System.out.println("-------------------------------");
        result = haveSameValue(text1, text2);
        System.out.println("result: "+result);
        
        System.out.println("\nTEST 2, clob vs string");
        System.out.println("----------------------");
        result = haveSameValue(clob1, text1);
        System.out.println("result: "+result);
        
        System.out.println("\nTEST 3, different clobs objects but same value");
        System.out.println("----------------------------------------------");
        result = haveSameValue(clob1, clob2);
        System.out.println("result: "+result);
        
        System.out.println("\nTEST 4, different clobs");
        System.out.println("-----------------------");
        result = haveSameValue(clob1, clob3);
        System.out.println("result: "+result);
    } 
    
    public static boolean haveSameValue(Object obj1, Object obj2) {
        String sObj1, sObj2, sObj1Class, sObj2Class;
        boolean result = false;

        if (obj1!=null && obj2!=null) {
            sObj1Class = obj1.getClass().toString().toLowerCase();
            sObj2Class = obj2.getClass().toString().toLowerCase();
            System.out.println("  Objects class : sObj1Class="+sObj1Class+", sObj2Class="+sObj2Class);

            System.out.println("  OBJECT : obj1="+obj1+", obj2="+obj2+", => equal as object? "+obj1.equals(obj2));
            
            if (!obj1.equals(obj2)) {
                sObj1=obj1.toString();
                sObj2=obj2.toString();
                System.out.println("  STRING : sObj1="+sObj1+", sObj2="+sObj2+", => equal as string? "+sObj1.equals(sObj2));
                
                if (!sObj1.equals(sObj2)) {                 
                    if (obj1 instanceof java.sql.Clob || obj2 instanceof java.sql.Clob) {
                        sObj1 = ClobToString(obj1);
                        sObj2 = ClobToString(obj2);
                        System.out.println("  CLOB : sObj1="+sObj1+", sObj2="+sObj2+" => equal as clob? "+sObj1.equals(sObj2));
                        result = sObj1.equals(sObj2);
                    }
                    
                    // other comparisons (as a date, timestamp, number...)
                }
            }
        }
        
        return result;
    }
    
    public static String ClobToString(Object object) {
        if (object==null) {
            return null;
        }
        else if (object instanceof java.sql.Clob) {
            StringBuilder sb = new StringBuilder();
            try {
                Reader reader = ((java.sql.Clob) object).getCharacterStream();
                BufferedReader br = new BufferedReader(reader);

                String line;
                while(null != (line = br.readLine())) {
                    sb.append(line);
                }
                br.close();
                return sb.toString();
            }
            catch (Exception e) {
                System.out.println("error : "+e.getMessage());
                return object.toString();
            }
        }
        else {
            return object.toString();
        }
    }
}
Source Link

how to test a method that uses clobs?

I have a method that compares the value of objects (as string, date, number...) and returns true or false depending of the result.

I've created a unit test for this method, but I'm having a problem testing the clob comparison, because with JUnit I don't have a connection, and if I use SerialClob to create two clobs (with the same content), I get objects with the same reference (so the part that compare clobs is not tested), I don't understand why two "new" generate the same object reference?

And another thing I don't understand, if I compare a string with a clob (identical values), the code that compares the clob is used, whereas instanceof is not supposed to be identical...! Here is my code (simplified for example):

import java.io.*;
import java.sql.*;
import javax.sql.rowset.serial.*;

public class TestClob {
    
    public static void main(String[] args) throws SerialException, SQLException {
        boolean result;
        Object text1="abcdef", text2="abcdef";
        Clob clob1 = new SerialClob(((String) text1).toCharArray());
        Clob clob2 = new SerialClob(((String) text2).toCharArray());
        Clob clob3 = new SerialClob("abcdefg".toCharArray());

        System.out.println("TEST 1, basic string comparison");
        System.out.println("-------------------------------");
        result = haveSameValue(text1, text2);
        System.out.println("result: "+result);
        
        System.out.println("\nTEST 2, clob vs string");
        System.out.println("----------------------");
        result = haveSameValue(clob1, text1);
        System.out.println("result: "+result);
        
        System.out.println("\nTEST 3, different clobs objects but same value");
        System.out.println("----------------------------------------------");
        result = haveSameValue(clob1, clob2);
        System.out.println("result: "+result);
        
        System.out.println("\nTEST 4, different clobs");
        System.out.println("-----------------------");
        result = haveSameValue(clob1, clob3);
        System.out.println("result: "+result);
    } 
    
    public static boolean haveSameValue(Object obj1, Object obj2) {
        String sObj1, sObj2, sObj1Class, sObj2Class;
        boolean result = true;

        if (obj1!=null && obj2!=null) {
            sObj1Class = obj1.getClass().toString().toLowerCase();
            sObj2Class = obj2.getClass().toString().toLowerCase();
            System.out.println("  Objects class : sObj1Class="+sObj1Class+", sObj2Class="+sObj2Class);

            System.out.println("  OBJECT : obj1="+obj1+", obj2="+obj2+", => equal as object? "+obj1.equals(obj2));
            
            if (!obj1.equals(obj2)) {
                sObj1=obj1.toString();
                sObj2=obj2.toString();
                System.out.println("  STRING : sObj1="+sObj1+", sObj2="+sObj2+", => equal as string? "+sObj1.equals(sObj2));
                
                if (!sObj1.equals(sObj2)) {                 
                    if (obj1 instanceof java.sql.Clob || obj2 instanceof java.sql.Clob) {
                        sObj1 = ClobToString(obj1);
                        sObj2 = ClobToString(obj2);
                        System.out.println("  CLOB : sObj1="+sObj1+", sObj2="+sObj2+" => equal as clob? "+sObj1.equals(sObj2));
                        result = sObj1.equals(sObj2);
                    }
                    
                    // other comparisons (as a date, timestamp, number...)
                }
            }
        }
        
        return result;
    }
    
    public static String ClobToString(Object object) {
        if (object==null) {
            return null;
        }
        else if (object instanceof java.sql.Clob) {
            StringBuilder sb = new StringBuilder();
            try {
                Reader reader = ((java.sql.Clob) object).getCharacterStream();
                BufferedReader br = new BufferedReader(reader);

                String line;
                while(null != (line = br.readLine())) {
                    sb.append(line);
                }
                br.close();
                return sb.toString();
            }
            catch (Exception e) {
                System.out.println("error : "+e.getMessage());
                return object.toString();
            }
        }
        else {
            return object.toString();
        }
    }
}

and here is the output:

TEST 1, basic string comparison
-------------------------------
  Objects class : sObj1Class=class java.lang.string, sObj2Class=class java.lang.string
  OBJECT : obj1=abcdef, obj2=abcdef, => equal as object? true
result: true

TEST 2, clob vs string
----------------------
  Objects class : sObj1Class=class javax.sql.rowset.serial.serialclob, sObj2Class=class java.lang.string
  OBJECT : obj1=javax.sql.rowset.serial.SerialClob@df59efc3, obj2=abcdef, => equal as object? false
  STRING : sObj1=javax.sql.rowset.serial.SerialClob@df59efc3, sObj2=abcdef, => equal as string? false
  CLOB : sObj1=abcdef, sObj2=abcdef => equal as clob? true
result: true

TEST 3, different clobs objects but same value
----------------------------------------------
  Objects class : sObj1Class=class javax.sql.rowset.serial.serialclob, sObj2Class=class javax.sql.rowset.serial.serialclob
  OBJECT : obj1=javax.sql.rowset.serial.SerialClob@df59efc3, obj2=javax.sql.rowset.serial.SerialClob@df59efc3, => equal as object? true
result: true

TEST 4, different clobs
-----------------------
  Objects class : sObj1Class=class javax.sql.rowset.serial.serialclob, sObj2Class=class javax.sql.rowset.serial.serialclob
  OBJECT : obj1=javax.sql.rowset.serial.SerialClob@df59efc3, obj2=javax.sql.rowset.serial.SerialClob@bd7d1c2, => equal as object? false
  STRING : sObj1=javax.sql.rowset.serial.SerialClob@df59efc3, sObj2=javax.sql.rowset.serial.SerialClob@bd7d1c2, => equal as string? false
  CLOB : sObj1=abcdef, sObj2=abcdefg => equal as clob? false
result: false