Thread: Retrieving arrays
Hello, I wrote this method to read arrays from my result set. public class MyClass { public <T> T[] getArray(ResultSet rs, String column) throws Exception { if(rs.getArray(column) != null) { return (T[]) rs.getArray(column).getArray(); } return null; } } I call i like this: String[] values = MyClass.<String>getArray(rs, "myStringArrayColumn")); This works fine. ( "myStringArrayColumn" is of type character varying(64)[]) But, when I call: Integer[] values = MyClass.<Integer>getArray(rs, "myIntegerArrayColumn")); ( "myIntegerArrayColumn" is of type integer[]) I get a: java.lang.ClassCastException: [I Any ideas? Thanks
Java 5 doesn't support auto-boxing an int[] as an Integer[]. -- Mark Lewis On Tue, 2006-10-10 at 15:15 +0200, Bendik Rognlien Johansen wrote: > Hello, > I wrote this method to read arrays from my result set. > > > public class MyClass { > public <T> T[] getArray(ResultSet rs, String column) throws > Exception { > if(rs.getArray(column) != null) { > return (T[]) rs.getArray(column).getArray(); > } > return null; > } > } > > > > I call i like this: > > String[] values = MyClass.<String>getArray(rs, "myStringArrayColumn")); > > This works fine. ( "myStringArrayColumn" is of type character > varying(64)[]) > > > But, when I call: > > Integer[] values = MyClass.<Integer>getArray(rs, > "myIntegerArrayColumn")); > ( "myIntegerArrayColumn" is of type integer[]) > > > I get a: > java.lang.ClassCastException: [I > > > Any ideas? > > Thanks > > ---------------------------(end of broadcast)--------------------------- > TIP 4: Have you searched our list archives? > > http://archives.postgresql.org
Ok, thanks! So, that probably means I can not do this sort of thing with Generics? Is there any way the driver could get the same behavior as the driver used in PL/Java? In PL/Java i can do: return (String[]) rs.getObject(column); On Oct 10, 2006, at 7:59 PM, Mark Lewis wrote: > Java 5 doesn't support auto-boxing an int[] as an Integer[]. > > -- Mark Lewis > > On Tue, 2006-10-10 at 15:15 +0200, Bendik Rognlien Johansen wrote: >> Hello, >> I wrote this method to read arrays from my result set. >> >> >> public class MyClass { >> public <T> T[] getArray(ResultSet rs, String column) throws >> Exception { >> if(rs.getArray(column) != null) { >> return (T[]) rs.getArray(column).getArray(); >> } >> return null; >> } >> } >> >> >> >> I call i like this: >> >> String[] values = MyClass.<String>getArray(rs, >> "myStringArrayColumn")); >> >> This works fine. ( "myStringArrayColumn" is of type character >> varying(64)[]) >> >> >> But, when I call: >> >> Integer[] values = MyClass.<Integer>getArray(rs, >> "myIntegerArrayColumn")); >> ( "myIntegerArrayColumn" is of type integer[]) >> >> >> I get a: >> java.lang.ClassCastException: [I >> >> >> Any ideas? >> >> Thanks >> >> ---------------------------(end of >> broadcast)--------------------------- >> TIP 4: Have you searched our list archives? >> >> http://archives.postgresql.org > > ---------------------------(end of > broadcast)--------------------------- > TIP 3: Have you checked our extensive FAQ? > > http://www.postgresql.org/docs/faq
Hi, bendik, Bendik Rognlien Johansen wrote: > I wrote this method to read arrays from my result set. > > public class MyClass { > public <T> T[] getArray(ResultSet rs, String column) throws Exception { > if(rs.getArray(column) != null) { > return (T[]) rs.getArray(column).getArray(); > } > return null; > } > } It seems that you misunderstand the concepts of Generics. Your method will call the getArray() method, and then try to cast (not convert) whatever this method returns into an T[]. And, due to erasure, this cast is not even done in MyClass.getArray(), but in the code that calls MyClass.getArray(). So getArray() does not even know about T, it just returns what its mapping of the PostgreSQL types to java tells it to. http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html should be a good reading, and in case of any doubts, http://java.sun.com/docs/books/jls/index.html > I call i like this: > > String[] values = MyClass.<String>getArray(rs, "myStringArrayColumn")); > > This works fine. ( "myStringArrayColumn" is of type character > varying(64)[]) Yes, it works fine. ResultSet.getArray maps the varchar[] to a String[], and then your 'String[] values=' assignment casts that to String[], which works fine. > But, when I call: > > Integer[] values = MyClass.<Integer>getArray(rs, "myIntegerArrayColumn")); > ( "myIntegerArrayColumn" is of type integer[]) > > I get a: > java.lang.ClassCastException: [I This one fails. ResultSet.getArray maps the integer[] to a int[], not to an Integer[]. And so, the cast will fail. HTH, Markus -- Markus Schaber | Logical Tracking&Tracing International AG Dipl. Inf. | Software Development GIS Fight against software patents in Europe! www.ffii.org www.nosoftwarepatents.org
Hello, yes you are right, I don't really understand Generics that well. But it is a little clearer now :-) Anyway, I was hoping there would be a clean way to get arrays from the result set, Generics or not, using a single method. I would like to avoid: getStringArray, getIntegerArray etc. The reason I need to do this is that I use two different drivers for PostgreSQL with the same code, and they handle arrays differently. Thanks! On Oct 11, 2006, at 2:42 PM, Markus Schaber wrote: > Hi, bendik, > > Bendik Rognlien Johansen wrote: > >> I wrote this method to read arrays from my result set. >> >> public class MyClass { >> public <T> T[] getArray(ResultSet rs, String column) throws >> Exception { >> if(rs.getArray(column) != null) { >> return (T[]) rs.getArray(column).getArray(); >> } >> return null; >> } >> } > > It seems that you misunderstand the concepts of Generics. > > Your method will call the getArray() method, and then try to cast (not > convert) whatever this method returns into an T[]. And, due to > erasure, > this cast is not even done in MyClass.getArray(), but in the code that > calls MyClass.getArray(). > > So getArray() does not even know about T, it just returns what its > mapping of the PostgreSQL types to java tells it to. > > http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html > should be > a good reading, and in case of any doubts, > http://java.sun.com/docs/books/jls/index.html > >> I call i like this: >> >> String[] values = MyClass.<String>getArray(rs, >> "myStringArrayColumn")); >> >> This works fine. ( "myStringArrayColumn" is of type character >> varying(64)[]) > > Yes, it works fine. ResultSet.getArray maps the varchar[] to a > String[], > and then your 'String[] values=' assignment casts that to String[], > which works fine. > >> But, when I call: >> >> Integer[] values = MyClass.<Integer>getArray(rs, >> "myIntegerArrayColumn")); >> ( "myIntegerArrayColumn" is of type integer[]) >> >> I get a: >> java.lang.ClassCastException: [I > > This one fails. ResultSet.getArray maps the integer[] to a int[], > not to > an Integer[]. And so, the cast will fail. > > > HTH, > Markus > > > -- > Markus Schaber | Logical Tracking&Tracing International AG > Dipl. Inf. | Software Development GIS > > Fight against software patents in Europe! www.ffii.org > www.nosoftwarepatents.org
Hi, Bendik, Bendik Rognlien Johansen wrote: > yes you are right, I don't really understand Generics that well. But it > is a little clearer now :-) > > Anyway, I was hoping there would be a clean way to get arrays from the > result set, Generics or not, using a single method. I would like to avoid: > getStringArray, getIntegerArray etc. Usually, ResultSet.getArray() should do it. > The reason I need to do this is that I use two different drivers for > PostgreSQL with the same code, and they handle arrays differently. So you say that the the other one (pljava, IIRC) maps a postgresql integer[] to an java.lang.Integer[] in java, and not an int[] like pgjdbc? Looks strange. Does the jdbc spec promote one or the other behaviour? However, I don't know a clean solution. Markus -- Markus Schaber | Logical Tracking&Tracing International AG Dipl. Inf. | Software Development GIS Fight against software patents in Europe! www.ffii.org www.nosoftwarepatents.org
On 11-Oct-06, at 9:43 AM, Markus Schaber wrote: > Hi, Bendik, > > Bendik Rognlien Johansen wrote: > >> yes you are right, I don't really understand Generics that well. >> But it >> is a little clearer now :-) >> >> Anyway, I was hoping there would be a clean way to get arrays from >> the >> result set, Generics or not, using a single method. I would like >> to avoid: >> getStringArray, getIntegerArray etc. > > Usually, ResultSet.getArray() should do it. > >> The reason I need to do this is that I use two different drivers for >> PostgreSQL with the same code, and they handle arrays differently. > > So you say that the the other one (pljava, IIRC) maps a postgresql > integer[] to an java.lang.Integer[] in java, and not an int[] like > pgjdbc? > > Looks strange. > > Does the jdbc spec promote one or the other behaviour? Yes, the spec, and the desire to not create a huge number of objects does promote one method over another pp 285 from JDBC API Tutorial and Reference 3rd Edition states "The data type for the elements is determined by the standard mapping from JDBC Types to Objects ... There is one very important exception to this rule. If the base type of the array maps to a primitive type in the Java programming language, the base type of the returned array will be the primitive type rather than the Object type" So I'd suggest you file a bug with pl/java Dave > > However, I don't know a clean solution. > > Markus > -- > Markus Schaber | Logical Tracking&Tracing International AG > Dipl. Inf. | Software Development GIS > > Fight against software patents in Europe! www.ffii.org > www.nosoftwarepatents.org > > ---------------------------(end of > broadcast)--------------------------- > TIP 3: Have you checked our extensive FAQ? > > http://www.postgresql.org/docs/faq >
Hello, In PL/Java: String[] values = (String[]) rs.getObject(column); Regular driver: String[] values = (String[]) rs.getArray(column).getArray(); Strange.. On Oct 11, 2006, at 3:43 PM, Markus Schaber wrote: > Hi, Bendik, > > Bendik Rognlien Johansen wrote: > >> yes you are right, I don't really understand Generics that well. >> But it >> is a little clearer now :-) >> >> Anyway, I was hoping there would be a clean way to get arrays from >> the >> result set, Generics or not, using a single method. I would like >> to avoid: >> getStringArray, getIntegerArray etc. > > Usually, ResultSet.getArray() should do it. > >> The reason I need to do this is that I use two different drivers for >> PostgreSQL with the same code, and they handle arrays differently. > > So you say that the the other one (pljava, IIRC) maps a postgresql > integer[] to an java.lang.Integer[] in java, and not an int[] like > pgjdbc? > > Looks strange. > > Does the jdbc spec promote one or the other behaviour? > > However, I don't know a clean solution. > > Markus > -- > Markus Schaber | Logical Tracking&Tracing International AG > Dipl. Inf. | Software Development GIS > > Fight against software patents in Europe! www.ffii.org > www.nosoftwarepatents.org
Hi, Bendik, Bendik Rognlien Johansen wrote: > In PL/Java: > String[] values = (String[]) rs.getObject(column); What does getArray() return here? > Regular driver: > String[] values = (String[]) rs.getArray(column).getArray(); And what does getObject return here? Thanks, Markus -- Markus Schaber | Logical Tracking&Tracing International AG Dipl. Inf. | Software Development GIS Fight against software patents in Europe! www.ffii.org www.nosoftwarepatents.org
Patches are welcome I haven't looked at the spec, but I also think this is outside of the spec, but we have discussed it and feel it is intuitive enough to accept. Dave On 13-Oct-06, at 4:58 AM, Bendik Rognlien Johansen wrote: > Hello, > > In PL/Java: > String[] values = (String[]) rs.getObject(column); > > Regular driver: > String[] values = (String[]) rs.getArray(column).getArray(); > > Strange.. > > On Oct 11, 2006, at 3:43 PM, Markus Schaber wrote: > >> Hi, Bendik, >> >> Bendik Rognlien Johansen wrote: >> >>> yes you are right, I don't really understand Generics that well. >>> But it >>> is a little clearer now :-) >>> >>> Anyway, I was hoping there would be a clean way to get arrays >>> from the >>> result set, Generics or not, using a single method. I would like >>> to avoid: >>> getStringArray, getIntegerArray etc. >> >> Usually, ResultSet.getArray() should do it. >> >>> The reason I need to do this is that I use two different drivers for >>> PostgreSQL with the same code, and they handle arrays differently. >> >> So you say that the the other one (pljava, IIRC) maps a postgresql >> integer[] to an java.lang.Integer[] in java, and not an int[] like >> pgjdbc? >> >> Looks strange. >> >> Does the jdbc spec promote one or the other behaviour? >> >> However, I don't know a clean solution. >> >> Markus >> -- >> Markus Schaber | Logical Tracking&Tracing International AG >> Dipl. Inf. | Software Development GIS >> >> Fight against software patents in Europe! www.ffii.org >> www.nosoftwarepatents.org > > > ---------------------------(end of > broadcast)--------------------------- > TIP 5: don't forget to increase your free space map settings >
Hello again. I have been away for a while. Column "stringarray" is VARCHAR[] Column "integerarray" is INTEGER[] System.out.println("getObject: " + rs.getObject ("integerarray").getClass()); System.out.println("getObject: " + rs.getObject ("stringarray").getClass()); System.out.println("getArray: " + rs.getArray("integerarray").getClass ()); System.out.println("getArray: " + rs.getArray("stringarray").getClass ()); Regular driver: getObject: class org.postgresql.jdbc3.Jdbc3Array getObject: class org.postgresql.jdbc3.Jdbc3Array getArray: class org.postgresql.jdbc3.Jdbc3Array getArray: class org.postgresql.jdbc3.Jdbc3Array PL/Java getObject: class [Ljava.lang.Integer; getObject: class [Ljava.lang.String; ERROR: java.sql.SQLException: Cannot derive a value of class java.sql.Array from an object of class [Ljava.lang.Integer; ERROR: java.sql.SQLException: Cannot derive a value of class java.sql.Array from an object of class [Ljava.lang.String; Thanks! On Oct 13, 2006, at 11:29 AM, Markus Schaber wrote: > Hi, Bendik, > > Bendik Rognlien Johansen wrote: > >> In PL/Java: >> String[] values = (String[]) rs.getObject(column); > > What does getArray() return here? > >> Regular driver: >> String[] values = (String[]) rs.getArray(column).getArray(); > > And what does getObject return here? > > Thanks, > Markus > -- > Markus Schaber | Logical Tracking&Tracing International AG > Dipl. Inf. | Software Development GIS > > Fight against software patents in Europe! www.ffii.org > www.nosoftwarepatents.org