views:

238

answers:

4

I am developing a java webapp, using jsp/jquery/ejb/jboss.

I have a web-form that enables the user to select any combination of 100 fields (all from different unrelated tables/objects) from the database. These fields are then output, via a java servlet, to an excel spreadsheet. A stored procedure is executed that always returns all 100 fields.

The web-form sets 100 boolean values in a transfer object(TO) to determine whether data should be then be displayed. This TO is then referenced to produce the title row of the spreadsheet and also for each row from database which is iterated over.

It all works fine, however it feels wrong. I cannot think of a viable way which does not reference 100 booleans (N+1 times) to determine whether a field should be included in the outputted spreadsheet. When I say viable I mean, for example, that I don't want to rewrite stored procedure or create 100 different stored procedures.

A: 

You could eliminate the manual field enumeration by:

  • on form load, for each of your available spreadsheet fields, you output a boolean control. Probably best to prepend some sort of prefix so you don't have conflicts with any other fields that exist on the form.

  • on form submission, you display any included fields that have the prefix.

Steve B.
+1  A: 

Instead of using a stored procedure for this couldn't you build your select SQL string dynamically in your application and then execute that SQL statement. So you only need to reference you booleans once and you only return the columns you need.

antonlavey
A: 

You'll have to evaluate whether this is really better, but you could use an approach where you use a bit array to store whether or not the fields are to be used. Each field would have a value corresponding to a single bit:

static final FIELD1 = 1;
static final FIELD2 = 2;
static final FIELD3 = 4;
static final FIELD4 = 8;
static final FIELD5 = 16;
etc

Each form field would have a value of its bit value when selected, or 0 when not selected. On form submission, total up the fields and submit the value. So if FIELD1 and FIELD3 were checked, you'd submit a value of 5 (00101 in binary).

Then you apply a simple bitmask for each field to determine which ones were selected (is there a better way than field-by-field?):

boolean field1Selected = sum & FIELD1;
boolean field2Selected = sum & FIELD2;
etc

Disadvantages: with 100 fields, you're talking about a really big number! You might have to use 2 bit arrays. I'm also not convinced that this really simplifies your problem, but maybe it does.

nojo
Does this just replace 100 bool fields with 100 bitmasks? Its true that it makes the TO smaller *in memory*, but is that the problem that the OP is trying to solve?
Andy Johnson
The produced number for storing the bitmask only just fits in the bounds of java max's value for an integer. I think. The TO is slightly smaller in memory,but thats the only benefit I can see. The original question is really about finding a "better way than field-by-field".
NimChimpsky
+2  A: 

Our solution was in similar situations to create a dynamic Transfer Object. Basically, it was a Map instead of a POJO having a number of getters and setters.

The codes which fills and reads this transfer object were simple iterations.

pcjuzer
Interesting. So in this example what would be the key/value ? Edit - pretty obvious actually I guess. The field identifer/col name as the key, and the value would be the data returned from database.
NimChimpsky
+1 I think this is a good solution. But rather than having 100 getters/setters to poulate the map, I'd have an enum of field names in the TO and a Dictionary<FieldEnum,bool> with two functions bool GetField(FieldEnum e) and void SetField(FieldEnum e, bool b).
Andy Johnson
+1 Choosing a Map over a "normal" TO/Bean is often a good way when you have to many properties where it makes no logical/semantic sense to split them into different objects. I also use that sometimes for method parameters when I have a lot of parameters and some of them are optional. Using an Enumeration for the field names is also a good choice. Often it's also good to wrap the map with a method that allows you to provide a default value that gets returned when the key is not set so you don't need to check for 'null' directly in your code.
Johannes Wachter
Anyway, I wouldn't put the Enumeration into the TO itself. I'd rather put them into some service interface. Thus, TO can become a very general class and when you add new elements to the service, TO needn't to be modified.
pcjuzer