FULL PRODUCT VERSION :
java version "1.6.0-beta2"
Java(TM) SE Runtime Environment (build 1.6.0-beta2-b86)
Java HotSpot(TM) Client VM (build 1.6.0-beta2-b86, mixed mode, sharing)
EXTRA RELEVANT SYSTEM CONFIGURATION :
using Derby database snapshot: db-derby-snapshot-10.2.0.3-412239
A DESCRIPTION OF THE PROBLEM :
The @Select.allColumnsMapped=true annotation value seems to conflict with a data class that uses @ResultColumn to map the table column to the field. When such a combination is used, the returned DataSet<T> does not contain any objects. If allColumnsMapped is false, not specified, or the data class does not have any @ResultColumn-mapped fields, everything works as expected.
I don't believe this is an issue with Derby since it appears that Derby uses the default QueryObjectGenerator implementation (com.sun.sql.QueryObjectGeneratorImpl).
ACTUAL -
The output of the attached program is:
Creating & opening DB
Create person table
Inserting 3 records into person table
Records inserted
Finding person records without 'allColumnsMapped'
DataSet size (should be 3): 3
Displaying all people
Smith
Johnson
Wagner
All people displayed
Finding person records *with* 'allColumnsMapped'
DataSet size (should be 3): 0
Displaying all people
All people displayed
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.sql.*;
public class QueryTest {
public static void main(String... args) throws Exception {
System.out.println("Creating & opening DB");
Connection conn = DriverManager.getConnection("jdbc:derby:queryTest;create=true");
System.out.println("Create person table");
PreparedStatement ps = conn.prepareStatement("create table person (last_name varchar(50))");
ps.execute();
ps.close();
System.out.println("Inserting 3 records into person table");
ps = conn.prepareStatement("insert into person values (?)");
ps.setString(1, "Smith");
ps.addBatch();
ps.setString(1, "Johnson");
ps.addBatch();
ps.setString(1, "Wagner");
ps.addBatch();
ps.executeBatch();
ps.close();
System.out.println("Records inserted");
System.out.println("Finding person records without 'allColumnsMapped'");
PersonQueries queries = conn.createQueryObject(PersonQueries.class);
DataSet<Person> people = queries.getAllPeople();
System.out.println("DataSet size (should be 3): " + people.size());
System.out.println("Displaying all people");
for (Person p : people) {
System.out.println(p.lastName);
}
System.out.println("All people displayed");
System.out.println("Finding person records *with* 'allColumnsMapped'");
people = queries.getAllPeopleBroken();
System.out.println("DataSet size (should be 3): " + people.size());
System.out.println("Displaying all people");
for (Person p : people) {
System.out.println(p.lastName);
}
System.out.println("All people displayed");
queries.close();
conn.close();
}
public static interface PersonQueries extends BaseQuery {
@Select(sql = "select last_name from person", allColumnsMapped = false)
DataSet<Person> getAllPeople();
@Select(sql = "select last_name from person", allColumnsMapped = true)
DataSet<Person> getAllPeopleBroken();
}
public static class Person {
@ResultColumn("last_name") public String lastName;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
The best workaround I've found is to leave allColumnsMapped = false (the default). The disadvantage is that allColumnsMapped = true would provide more runtime safety in some use cases.
java version "1.6.0-beta2"
Java(TM) SE Runtime Environment (build 1.6.0-beta2-b86)
Java HotSpot(TM) Client VM (build 1.6.0-beta2-b86, mixed mode, sharing)
EXTRA RELEVANT SYSTEM CONFIGURATION :
using Derby database snapshot: db-derby-snapshot-10.2.0.3-412239
A DESCRIPTION OF THE PROBLEM :
The @Select.allColumnsMapped=true annotation value seems to conflict with a data class that uses @ResultColumn to map the table column to the field. When such a combination is used, the returned DataSet<T> does not contain any objects. If allColumnsMapped is false, not specified, or the data class does not have any @ResultColumn-mapped fields, everything works as expected.
I don't believe this is an issue with Derby since it appears that Derby uses the default QueryObjectGenerator implementation (com.sun.sql.QueryObjectGeneratorImpl).
ACTUAL -
The output of the attached program is:
Creating & opening DB
Create person table
Inserting 3 records into person table
Records inserted
Finding person records without 'allColumnsMapped'
DataSet size (should be 3): 3
Displaying all people
Smith
Johnson
Wagner
All people displayed
Finding person records *with* 'allColumnsMapped'
DataSet size (should be 3): 0
Displaying all people
All people displayed
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.sql.*;
public class QueryTest {
public static void main(String... args) throws Exception {
System.out.println("Creating & opening DB");
Connection conn = DriverManager.getConnection("jdbc:derby:queryTest;create=true");
System.out.println("Create person table");
PreparedStatement ps = conn.prepareStatement("create table person (last_name varchar(50))");
ps.execute();
ps.close();
System.out.println("Inserting 3 records into person table");
ps = conn.prepareStatement("insert into person values (?)");
ps.setString(1, "Smith");
ps.addBatch();
ps.setString(1, "Johnson");
ps.addBatch();
ps.setString(1, "Wagner");
ps.addBatch();
ps.executeBatch();
ps.close();
System.out.println("Records inserted");
System.out.println("Finding person records without 'allColumnsMapped'");
PersonQueries queries = conn.createQueryObject(PersonQueries.class);
DataSet<Person> people = queries.getAllPeople();
System.out.println("DataSet size (should be 3): " + people.size());
System.out.println("Displaying all people");
for (Person p : people) {
System.out.println(p.lastName);
}
System.out.println("All people displayed");
System.out.println("Finding person records *with* 'allColumnsMapped'");
people = queries.getAllPeopleBroken();
System.out.println("DataSet size (should be 3): " + people.size());
System.out.println("Displaying all people");
for (Person p : people) {
System.out.println(p.lastName);
}
System.out.println("All people displayed");
queries.close();
conn.close();
}
public static interface PersonQueries extends BaseQuery {
@Select(sql = "select last_name from person", allColumnsMapped = false)
DataSet<Person> getAllPeople();
@Select(sql = "select last_name from person", allColumnsMapped = true)
DataSet<Person> getAllPeopleBroken();
}
public static class Person {
@ResultColumn("last_name") public String lastName;
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
The best workaround I've found is to leave allColumnsMapped = false (the default). The disadvantage is that allColumnsMapped = true would provide more runtime safety in some use cases.