DataSet.sync is thowing a SQLRuntimeException instead of SQLDataSetSyncException when DataSet.delete had deleted a row. At the same time, the data from the data source had changed before the DataSet.sync is called.
1) Query data to DataSet as a disconnected mode.
2) remove the row with ID=1.
3) Using ResultSet to modify the data in last name column where ID=1
4) DataSet.sync is call.
5) It should have SQLDataSetSyncException not SQLRuntimeException since the data from the data source wasn't same a what DataSet queried before.
Running the sample program.
=============================
Change the DB IP, username, passed.
1) javac QueryTest.java
2) java QueryTest
Output
=======
java version "1.6.0-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0-rc-b63)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b63, mixed mode)
Calling query.getAllPersons() ...
DataSet.size=2
Delete from DataSet Id: 1 First Name: fname1 Last Name: last_name1
Updated the ResultSet row
Calling the rows.sync()
SQLRuntimeException java.lang.IllegalArgumentException: Can not set long field PersonDO.id to java.math.BigDecimal
After syncing....
Id: 1 First Name: ResultSetChanged Last Name: last_name1
Id: 2 First Name: fname2 Last Name: last_name2
Sample Program
===============
PersonDO.java
----------
import java.sql.ResultColumn;
public class PersonDO {
@ResultColumn(uniqueIdentifier=true)public long id ;
//public long id ;
public String firstName ;
public String lastName ;
}
QueryTest.java
-------------------
import java.sql.*;
public class QueryTest {
Connection conn = null;
Connection conn1 = null;
Statement stmt = null;
private void doSetup() {
try {
Class.forName("com.inet.ora.OraDriver");
}catch (ClassNotFoundException ex) {
System.err.println("Exception when loading JDBC driver : "+ex);
}
try {
conn = DriverManager.getConnection("jdbc:inetora:IP:1521:ORCL", "user", "passwd");
conn1 = DriverManager.getConnection("jdbc:inetora:IP:1521:ORCL", "user", "passwd");
stmt = conn.createStatement();
stmt.executeUpdate("drop table query001");
}catch (SQLException ex) {
System.err.println("Exception : "+ex);
}
try {
stmt.addBatch("create table query001 ( id number, firstName varchar2(32), lastName varchar2(32), primary key (id))");
stmt.addBatch("insert into query001 values ( 1, 'fname1', 'last_name1')");
stmt.addBatch("insert into query001 values ( 2, 'fname2', 'last_name2')");
stmt.executeBatch();
}catch (SQLException ex) {
System.err.println("Exception when executing SQL :"+ex);
}
}
private void doTest() {
DataSet<PersonDO> rows = null;
I_Query001 query = null;
try {
query = QueryObjectFactory.createQueryObject(I_Query001.class, conn);
} catch (SQLException sqlEx) {
System.err.println("SQLException caught "+sqlEx.getMessage());
}
System.out.println("Calling query.getAllPersons() ...");
rows = query.getAllPersons();
System.out.println("DataSet.size="+rows.size());
for(PersonDO p : rows) {
if( p.id == 1) {
//p.firstName = "syncproblemFirst";
//rows.modify();
rows.delete();
System.out.println("Delete from DataSet Id: "+p.id+" First Name: "+p.firstName+" Last Name: "+p.lastName);
}
}
// Here change the value in the DB. This should cause a sync problem.
try {
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("select * from query001");
while(rs.next()) {
if(rs.getInt(1) == 1) {
rs.updateString(2,"ResultSetChanged");
rs.updateRow();
System.out.println("Updated the ResultSet row");
}
}
} catch(Exception e) {
System.out.println("Unexpected Exception: "+e.getMessage());
}
try
{
System.out.println("Calling the rows.sync()");
rows.sync();
} catch(SQLDataSetSyncException spe) {
System.out.println("Caught : "+spe.getMessage());
DataSetResolver<ConflictingRow> ds = spe.getDataSetResolver();
for(ConflictingRow cr : ds) {
PersonDO pd = (PersonDO)cr.getRow();
System.out.println("Conflicted pd id: "+pd.id);
System.out.println("Conflicted pd firstName: "+pd.firstName);
System.out.println("Conflicted pd lastName: "+pd.lastName);
//pd.firstName = "thiiswrong";
//pd.firstName = "syncproblemFirst";
//ds.syncRow();
}
ds.sync();
} catch(SQLRuntimeException SRE){
System.out.println("SQLRuntimeException " + SRE.getMessage());
}
rows = query.getAllPersons();
System.out.println("After syncing....");
for(PersonDO p : rows) {
System.out.println("Id: "+p.id+" First Name: "+p.firstName+" Last Name: "+p.lastName);
}
/*
System.out.println("Modify again ....");
for(PersonDO p : rows) {
if( p.id == 1)
p.firstName = "ModifyAgainFirst";
rows.modify();
System.out.println("Id: "+p.id+" First Name: "+p.firstName+" Last Name: "+p.lastName);
}
try
{
rows.sync();
} catch(SQLDataSetSyncException spe) {
System.out.println ("SQLDataSetSyncExc again");
}*/
}
public static void main(String[] args) {
QueryTest qtest = new QueryTest();
qtest.doSetup();
qtest.doTest();
}
}
interface I_Query001 extends BaseQuery {
@Select(sql="SELECT id , firstName, lastName from query001",connected=false,tableName="query001",readOnly=false)
DataSet<PersonDO> getAllPersons() ;
}
Please make this change in the sample so it will show better error message.
from: System.out.println("SQLRuntimeException " + SRE.getMessage());
to: SRE.printStackTrace();
StackTrack output
==================
java.sql.SQLRuntimeException: java.lang.IllegalArgumentException: Can not set int field PersonDO.id to java.math.BigDecimal
at com.sun.sql.DataSetImpl.sync(DataSetImpl.java:1281)
at com.sun.sql.DataSetImpl.sync(DataSetImpl.java:1242)
at QueryTest.doTest(QueryTest.java:79)
at QueryTest.main(QueryTest.java:124)
Caused by: java.lang.IllegalArgumentException: Can not set int field PersonDO.id to java.math.BigDecimal
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
at sun.reflect.UnsafeIntegerFieldAccessorImpl.set(UnsafeIntegerFieldAccessorImpl.java:80)
at java.lang.reflect.Field.set(Field.java:656)
at com.sun.sql.DataSetImpl.processSyncFailures(DataSetImpl.java:1341)
at com.sun.sql.DataSetImpl.sync(DataSetImpl.java:1276)
... 3 more
1) Query data to DataSet as a disconnected mode.
2) remove the row with ID=1.
3) Using ResultSet to modify the data in last name column where ID=1
4) DataSet.sync is call.
5) It should have SQLDataSetSyncException not SQLRuntimeException since the data from the data source wasn't same a what DataSet queried before.
Running the sample program.
=============================
Change the DB IP, username, passed.
1) javac QueryTest.java
2) java QueryTest
Output
=======
java version "1.6.0-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0-rc-b63)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b63, mixed mode)
Calling query.getAllPersons() ...
DataSet.size=2
Delete from DataSet Id: 1 First Name: fname1 Last Name: last_name1
Updated the ResultSet row
Calling the rows.sync()
SQLRuntimeException java.lang.IllegalArgumentException: Can not set long field PersonDO.id to java.math.BigDecimal
After syncing....
Id: 1 First Name: ResultSetChanged Last Name: last_name1
Id: 2 First Name: fname2 Last Name: last_name2
Sample Program
===============
PersonDO.java
----------
import java.sql.ResultColumn;
public class PersonDO {
@ResultColumn(uniqueIdentifier=true)public long id ;
//public long id ;
public String firstName ;
public String lastName ;
}
QueryTest.java
-------------------
import java.sql.*;
public class QueryTest {
Connection conn = null;
Connection conn1 = null;
Statement stmt = null;
private void doSetup() {
try {
Class.forName("com.inet.ora.OraDriver");
}catch (ClassNotFoundException ex) {
System.err.println("Exception when loading JDBC driver : "+ex);
}
try {
conn = DriverManager.getConnection("jdbc:inetora:IP:1521:ORCL", "user", "passwd");
conn1 = DriverManager.getConnection("jdbc:inetora:IP:1521:ORCL", "user", "passwd");
stmt = conn.createStatement();
stmt.executeUpdate("drop table query001");
}catch (SQLException ex) {
System.err.println("Exception : "+ex);
}
try {
stmt.addBatch("create table query001 ( id number, firstName varchar2(32), lastName varchar2(32), primary key (id))");
stmt.addBatch("insert into query001 values ( 1, 'fname1', 'last_name1')");
stmt.addBatch("insert into query001 values ( 2, 'fname2', 'last_name2')");
stmt.executeBatch();
}catch (SQLException ex) {
System.err.println("Exception when executing SQL :"+ex);
}
}
private void doTest() {
DataSet<PersonDO> rows = null;
I_Query001 query = null;
try {
query = QueryObjectFactory.createQueryObject(I_Query001.class, conn);
} catch (SQLException sqlEx) {
System.err.println("SQLException caught "+sqlEx.getMessage());
}
System.out.println("Calling query.getAllPersons() ...");
rows = query.getAllPersons();
System.out.println("DataSet.size="+rows.size());
for(PersonDO p : rows) {
if( p.id == 1) {
//p.firstName = "syncproblemFirst";
//rows.modify();
rows.delete();
System.out.println("Delete from DataSet Id: "+p.id+" First Name: "+p.firstName+" Last Name: "+p.lastName);
}
}
// Here change the value in the DB. This should cause a sync problem.
try {
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("select * from query001");
while(rs.next()) {
if(rs.getInt(1) == 1) {
rs.updateString(2,"ResultSetChanged");
rs.updateRow();
System.out.println("Updated the ResultSet row");
}
}
} catch(Exception e) {
System.out.println("Unexpected Exception: "+e.getMessage());
}
try
{
System.out.println("Calling the rows.sync()");
rows.sync();
} catch(SQLDataSetSyncException spe) {
System.out.println("Caught : "+spe.getMessage());
DataSetResolver<ConflictingRow> ds = spe.getDataSetResolver();
for(ConflictingRow cr : ds) {
PersonDO pd = (PersonDO)cr.getRow();
System.out.println("Conflicted pd id: "+pd.id);
System.out.println("Conflicted pd firstName: "+pd.firstName);
System.out.println("Conflicted pd lastName: "+pd.lastName);
//pd.firstName = "thiiswrong";
//pd.firstName = "syncproblemFirst";
//ds.syncRow();
}
ds.sync();
} catch(SQLRuntimeException SRE){
System.out.println("SQLRuntimeException " + SRE.getMessage());
}
rows = query.getAllPersons();
System.out.println("After syncing....");
for(PersonDO p : rows) {
System.out.println("Id: "+p.id+" First Name: "+p.firstName+" Last Name: "+p.lastName);
}
/*
System.out.println("Modify again ....");
for(PersonDO p : rows) {
if( p.id == 1)
p.firstName = "ModifyAgainFirst";
rows.modify();
System.out.println("Id: "+p.id+" First Name: "+p.firstName+" Last Name: "+p.lastName);
}
try
{
rows.sync();
} catch(SQLDataSetSyncException spe) {
System.out.println ("SQLDataSetSyncExc again");
}*/
}
public static void main(String[] args) {
QueryTest qtest = new QueryTest();
qtest.doSetup();
qtest.doTest();
}
}
interface I_Query001 extends BaseQuery {
@Select(sql="SELECT id , firstName, lastName from query001",connected=false,tableName="query001",readOnly=false)
DataSet<PersonDO> getAllPersons() ;
}
Please make this change in the sample so it will show better error message.
from: System.out.println("SQLRuntimeException " + SRE.getMessage());
to: SRE.printStackTrace();
StackTrack output
==================
java.sql.SQLRuntimeException: java.lang.IllegalArgumentException: Can not set int field PersonDO.id to java.math.BigDecimal
at com.sun.sql.DataSetImpl.sync(DataSetImpl.java:1281)
at com.sun.sql.DataSetImpl.sync(DataSetImpl.java:1242)
at QueryTest.doTest(QueryTest.java:79)
at QueryTest.main(QueryTest.java:124)
Caused by: java.lang.IllegalArgumentException: Can not set int field PersonDO.id to java.math.BigDecimal
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
at sun.reflect.UnsafeIntegerFieldAccessorImpl.set(UnsafeIntegerFieldAccessorImpl.java:80)
at java.lang.reflect.Field.set(Field.java:656)
at com.sun.sql.DataSetImpl.processSyncFailures(DataSetImpl.java:1341)
at com.sun.sql.DataSetImpl.sync(DataSetImpl.java:1276)
... 3 more