Need to add free method to Array interface
Standard SQL supports LOCATORs for BLOBs, CLOBs, NCLOBs, UDTs, ARRAYs, and MULTISETs.
(as is pointed out in JDBC's section:: Taxonomy of SQL Types)
Further, the JDBC spec says:
By default, a JDBC driver should implement the Array interface using an SQL LOCATOR(array) internally. Also by default, Array objects remain valid only during the transaction in which they are created.
Need to add Connection.createQueryObject(Class,Connection) and DataSource.createQueryObject(Class,DataSource) to allow for wrapped implementations of a DataSource/Connection to work correctly with EoD
his is not a problem introduced by the new public interface Wrappers, it is a problem for AppServers like WebSphere (to name one) and others that actively wrap JDBC's objects introduced by EoD. That said, there is a bug in the specification of the Wrapper that needs to be fixed too, but first let's deal with the EoD problem.
Consider the following example.
public class Mammal {
public String name;
public String description;
public int age;
}
interface MyQueries extends BaseQuery {
@Select("select name, description, age from mammal")
DataSet<Mammal> getAllMammals();
}
MyQueries mq = con.createQueryObject(MyQueries.class);
DataSet rows = mq.getAllMammals();
The way wrappers normally are thought to work is that they provided the Connection object con, and hence saw the invocation of con.createQueryObject, and might choose to wrapper the returned Object MyQueries mq, before it is returned to the calling application.
But, of what use is it to wrapper an instance of MyQueries? No wrapper would be able to derive anything useful from seeing invocation of mq.getAllMammals(). The wrapper couldn't know what, if any, JDBC activity took place inside getAllMammals. And, the whole point of wrappers is that they see all JDBC activity for any DBMS Connection they provide.
Why, you ask, wouldn't the wrapper have visibility of JDBC activity (in this case, executeQuery for the "select name, description, age from mammal")?
Consider, I'm a wrapper for a Connection given a call to createQueryObject; I do whatever I want associated with that invocation and pass it on to the instance of the Connection I wrap. In other words, I eventually do:
MyQueries toBeWrapped = wrappedConnection.createQueryObject(MyQueries.class);
Zero or more wrappers repeat that activity, each passing the createQueryObject(MyQueries.class) to an innermore Connection. Eventually, the actual JDBC Driver and the actual non-wrapped Connection.createQueryObject(MyQueries.class) is invoked. At that point the current, innermost, wrapper does not have any knowledge of outermore wrappers, nor does the JDBC Driver.
So, when the JDBC Driver's implementation of createQueryObject processes MyQueries.class, all JDBC activity that eventually results from mq.getAllMammals() is done directly on the Connection that the JDBC Driver owns/controls, not on any of the Connection wrappers. Hence, all this JDBC activity is invisible to the wrappers.
And, in a nutshell, that isn't acceptable.
Standard SQL supports LOCATORs for BLOBs, CLOBs, NCLOBs, UDTs, ARRAYs, and MULTISETs.
(as is pointed out in JDBC's section:: Taxonomy of SQL Types)
Further, the JDBC spec says:
By default, a JDBC driver should implement the Array interface using an SQL LOCATOR(array) internally. Also by default, Array objects remain valid only during the transaction in which they are created.
Need to add Connection.createQueryObject(Class,Connection) and DataSource.createQueryObject(Class,DataSource) to allow for wrapped implementations of a DataSource/Connection to work correctly with EoD
his is not a problem introduced by the new public interface Wrappers, it is a problem for AppServers like WebSphere (to name one) and others that actively wrap JDBC's objects introduced by EoD. That said, there is a bug in the specification of the Wrapper that needs to be fixed too, but first let's deal with the EoD problem.
Consider the following example.
public class Mammal {
public String name;
public String description;
public int age;
}
interface MyQueries extends BaseQuery {
@Select("select name, description, age from mammal")
DataSet<Mammal> getAllMammals();
}
MyQueries mq = con.createQueryObject(MyQueries.class);
DataSet rows = mq.getAllMammals();
The way wrappers normally are thought to work is that they provided the Connection object con, and hence saw the invocation of con.createQueryObject, and might choose to wrapper the returned Object MyQueries mq, before it is returned to the calling application.
But, of what use is it to wrapper an instance of MyQueries? No wrapper would be able to derive anything useful from seeing invocation of mq.getAllMammals(). The wrapper couldn't know what, if any, JDBC activity took place inside getAllMammals. And, the whole point of wrappers is that they see all JDBC activity for any DBMS Connection they provide.
Why, you ask, wouldn't the wrapper have visibility of JDBC activity (in this case, executeQuery for the "select name, description, age from mammal")?
Consider, I'm a wrapper for a Connection given a call to createQueryObject; I do whatever I want associated with that invocation and pass it on to the instance of the Connection I wrap. In other words, I eventually do:
MyQueries toBeWrapped = wrappedConnection.createQueryObject(MyQueries.class);
Zero or more wrappers repeat that activity, each passing the createQueryObject(MyQueries.class) to an innermore Connection. Eventually, the actual JDBC Driver and the actual non-wrapped Connection.createQueryObject(MyQueries.class) is invoked. At that point the current, innermost, wrapper does not have any knowledge of outermore wrappers, nor does the JDBC Driver.
So, when the JDBC Driver's implementation of createQueryObject processes MyQueries.class, all JDBC activity that eventually results from mq.getAllMammals() is done directly on the Connection that the JDBC Driver owns/controls, not on any of the Connection wrappers. Hence, all this JDBC activity is invisible to the wrappers.
And, in a nutshell, that isn't acceptable.