Today we had a problem with our web application when database was updated but web application was not restarted.
After investigation we found that during db update one user defined type was dropped and created again.
Type was not changed - it was just dropped and created again using the same sql statement as it was before.
Following code can show this problem.
There is java.sql.SQLSyntaxErrorException "ORA-00902: invalid datatype" when second prepared statement is executed.
String str = "select * from MYTESTTABLE where test in (select column_value from TABLE (?) tmp)";
OracleConnection conn = null;
Properties connectionProps = new Properties();
connectionProps.put("user", "user");
connectionProps.put("password", "pwd");
conn = (OracleConnection) DriverManager
.getConnection("conn", connectionProps);
Statement stmt = conn.createStatement();
stmt.execute("drop table mytesttable");
stmt.execute("create table MYTESTTABLE ( test NUMBER(22))");
System.out.println("Table MYTESTTABLE was created");
stmt.execute("drop type my_type");
System.out.println("Type my_type was dropped");
stmt.execute("create type my_type as table of NUMBER(22)");
System.out.println("Type my_type was created");
String[] northEastRegion = { "10022", "02110", "07399" };
oracle.sql.ARRAY arr1 = new oracle.sql.ARRAY(
oracle.sql.ArrayDescriptor.createDescriptor("MY_TYPE", conn),
conn, northEastRegion);
PreparedStatement ps = conn.prepareStatement(str);
ps.setArray(1, arr1);
ps.executeQuery();
stmt.execute("drop type my_type");
System.out.println("Type my_type was dropped");
stmt.execute("create type my_type as table of NUMBER(22)");
System.out.println("Type my_type was created");
oracle.sql.ARRAY arr2 = new oracle.sql.ARRAY(
oracle.sql.ArrayDescriptor.createDescriptor("MY_TYPE", conn),
conn, northEastRegion);
ps = conn.prepareStatement(str);
ps.setArray(1, arr2);
ps.executeQuery(); //java.sql.SQLSyntaxErrorException: ORA-00902: invalid datatype
Why arr1 and arr2 are treated as different types?
As I understand the problem is that these types have different OID.
But in java code I work with these types only by name. I do not use OID.
How to deal with this problem?
Should we always restart web application after update of DB? Even if structure of DB was not changed.
Or should we specify(hardcode) OID when we create MY_TYPE?
What is the correct way?
UPDATE:
It seems to me that I've found the answer and a bug in oracle.sql.ArrayDescriptor.
See my answer below.