Lightweight R/O Mapping
Subject:   Generics and Roundtrips
Date:   2005-12-12 10:11:37
From:   SeanReilly
Response to: Generics and Roundtrips

So, when I wrote that

ArrayList<T> list = reader.executeCreateBeanList( "..." );

will have the compiler issue a warning, I am right.

Ahem. While technically true that you are able to understand why the compiler has an issue with your code, that doesn't change the fact that you weren't correctly dealing with the issue.

From your article:

The compiler will issue a warning here, since the reader only knows at runtime what kind of class it is going to create. Because of type erasure in the generics implementation of J2SE 5.0, it is not possible to safely cast the result. And, sadly, it is also not possible to write the BeanReader class as BeanReader<Jedi> for the same reason. In short, using Java reflection and generics don't mix.

The original article claims that this kind of operation is "not possible". I provided you with a code example that proves that it is, if you use the correct syntax. You then replied that you were correct in describing the original compiler warning. This doesn't have much to do with the very relevant fact that the framework and example use the wrong syntax.

you've raised a philosophical question: Suppose your code works, I'd agree that it is explicit, but is it more concise? Considering type erasure and the fact that I need T.class to dynamically construct the required object (say, of type Jedi) would it be better to have a generified class BeanReader<Class<T>> to get rid of the unchecked type warning even though this information cannot be accessed for reflection? It might be nice to read, but seems cumbersome to code, wouldn't you say?

Your philosophical objections to the correct syntax are between you and the people at Sun responsible for Java language syntax. Until such time as the offical language spec changes to accomodate your preference, choosing convenient syntax over over correct syntax is a bug. That is precisely why the compiler warns you about it.

You are
right: In the example you brought up, the code I showed would
perform poorly. What I did not show is that Amber supports you,
if you wanted to join the Jedis and the Fighters on the database return a result set that contains Jedis (redundantly in their respective columns) and their Fighters (individually). You'd then create a class that holds a Jedi plus one single Fighter, load a list of this class (1 database query) and wrap it in mapper code where you'd extract the Jedis with their Fighter list.

Ah, I see. By "supports you", you really mean "allows you to do all of the work yourself". The primary requirement of an O/R framework is to convert relations into object hierarchies (hence the name). A framework that doesn't do this is basically useless. All this code provides is the simple ability to use reflection to unmarshall a simple result set into a simple object (or list of objects), but not a hierarchy. In other words, this is something that one could eventually use to build an O/R framework, but it isn't one itself.

This begs the question, why would you want to load 10000 Jedis into the client? If the user will filter them, this should be done in the database, right?

10000 was used as an example to illustrate the ridiculous absurdity of the example's performance. The code is still bad even if it returns only a half dozen results, but it is less obvious to the untrained eye.

1 to 2 of 2
1 to 2 of 2