Last week, we had the author of TDD for a Shopping Website LiveProject. Friday at 11am Ranch time, Steven Solomon will be hosting a live TDD session just for us. See for the agenda and registration link

Jon Egan

Ranch Hand
+ Follow
since Mar 24, 2004
Cows and Likes
Cows
Total received
0
In last 30 days
0
Total given
0
Likes
Total received
0
Received in last 30 days
0
Total given
0
Given in last 30 days
0
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Jon Egan

Pankaj,

I know this is probably 3 weeks too late for your assignment, but hopefully it will help the next person.

You could capture the result of the SQL update in edit.jsp, and pass a parameter in the URL when you redirect back to show.jsp. For example, the java code in your JSP could be something like:



Then in show.jsp, you would need to check for the presence of a request parameter named "updateResult", and display a message accordingly.

A few general notes about this:
  • it isn't best practice to have a lot of Java code in your JSPs
  • the value of "updateResult" parameter should really be URL encoded before it is added to redirectUrl on line 8
  • depending how you did your redirect in edit.jsp, the part of the HTML page that includes the alert might never be sent to the browser



  • 1 year ago
    JSP
    Vivek,

    It sounds like the piece you might be missing is this: if you don't define one or both of equals() or hashcode(), the method(s) you don't define are inherited from Object. The definitions of those methods in the Object class are not necessarily what you need for your application (just what does "equal" really mean in your app? what should constitute a "duplicate"?). But, the Object class implementations are consistent with each other, and fulfill the "hashcode contract".

    So, to address your 4 cases:

    1. Only equals method is implemented
    2. only hashCode method is implemented
    3. equals and hashCode method does not obey correct implemetation contract.
    4. Both equals and hashCode methods are NOT implemented.

    Case 1 & 2:
    it depends on whether the method that is implemented is done in a way that is still "consistent with" the other method definition, inherited from Object. If the two methods, taken together, still abide by the contract, your Map and Set will work as expected.

    More likely, this is not the case - usually one of these methods is overridden in a way that is meaningful for that particular class (considering certain key instance variables), and end up no longer being consistent with the inherited implementation of the other method.

    Case 3:
    The HashMap and HashSet will not work as expected in this case.

    Case 4:
    will work "properly" with a Map and Set, assuming you want things to be considered "duplicates" or not based on the Object.equals() definition... duplicates would be prevented when that method would return true (that is, they are the exact same object instance).


    Hope this helps,
    -- Jon
    ok, timing of my last reply looked like I was addressing Stan's post, but I just type slowly ;-).

    Now I am addressing Stan's post.

    Stan wrote:



    This should have been (bolded where it is changed):



    -- Jon
    16 years ago
    Slight correction... say you are talking about a class named com.acme.whizbang.SpiffyThing:



    does not return a "SpiffyThing" object.... it returns a java.lang.Class object... in other words, an instance of the class "java.lang.Class".... that object represents the class com.acme.whizbang.SpiffyThing, in the same way that an Integer object can represent an int value, or a Double represents a double. The Class object has methods to get information about the SpiffyThing class. It also has the following method:



    The Class method newInstance() is a way to instantiate (get an object of) a class when you don't know the name of the class until runtime (for example, maybe it came out of a database). A lot of times, this is the only reason you need the Class object, so those two lines are combined into one (and no reference to the Class object is kept):



    That works out to be the same as:




    Anyway, if you're at the point in your understanding where you're not clear about the distinction between classes and objects, just be aware that java.lang.Class exists, and that it can be a source of confusion.

    class - blueprint for, or type of, object
    object - a manifestation of the blueprint
    instance - synonym for Object

    Hope this helps
    -- Jon
    16 years ago
    I agree, I think you would need to use a loop.... but here are some really bad alternatives, just for fun:


    // Could probably be improved with some Pattern matching, and could
    // definitely be improved with fewer (ideally 1) invocation of
    // Arrays.toString().... but what fun would that be?
    ((Arrays.toString(bb).indexOf(" 0,") < 0) &&
    (Arrays.toString(bb).indexOf("[0,") < 0) &&
    (Arrays.toString(bb).indexOf(" 0]") < 0) &&
    (!Arrays.toString(bb).equals("[0]"))


    // Have to clone only if you want to maintain the original ordering
    Arrays.sort(bb.clone()).binarySearch((byte)0)


    // hrmmm.... I bet this is looping internally anyway...
    Arrays.aslist(bb).contains((byte)0)


    Alright, enough foolishness. Good luck,
    -- Jon
    16 years ago
    Some definitions and typical uses of Serialization might clear it up:

    definitions:

    1. state of an object - the values of the instance variables of the object... including the instance variables of any object-type instance variable of this object, and the instance variables held by ... see recursion.

    2. persistent medium - disk file, database, etc.... something not "in memory".


    Where an object is an "in-memory" concept, Serialization is the "not in memory" way to store an object, so it can be brought back into memory later, or by a different process.

    examples:

    1. Your app needs to shut down, and start up again later, with the same "state" (variables having the same value as before). You can write out the object-type variables to disk or a database by serializing them.

    2. Your app needs to "talk to" another app across a network, and share data that are represented in-memory as objects that both apps understand. With serialization, you can send the objects across a socket connection with the other app. (Note that this example isn't about a "persistent medium",it's a different use of serialization)

    Serialization is conceptually like this:



    At this point, you don't have the exact same object (that is, xp and xp2 are at different memory addresses, possibly in different processes, possibly on a different server)... but you have an equivalent object, one with the exact same state.


    Hope this helps,
    -- Jon
    16 years ago
    Paul,

    Look into using two queries combined with UNION.... and check into the difference between UNION and UNION ALL, to be sure you use the right one.

    Hope this helps,
    -- Jon
    16 years ago
    I think AJAX is perfectly acceptable for a chat app....

    A little story...

    My company, and the company at which some of my friends work, have blocked/banned use of most common chat apps except the company-hosted, internal-only app. This interfered with the most important task of arranging lunch.

    I had done a lot of web-based programming, and had once, 2-3 years ago, had one occasion to hear about... not even use... XmlHttpRequest. It occured to me that I could possibly develop a browser-based chat that we could use to set up lunch. Even without having "AJAX experience", the development was quick (this stuff was surprisingly easy). The chat works, and the only reason we don't use it today is that I don't have a good stable place to host it for free.... and I don't want to bother reworking it. We found the "demo" page of a site selling an AJAX chat, and we use that instead.

    After I was mostly done with the chat site, I saw something on Slashdot (or somewhere like that) talking about AJAX, and found out I had been doing AJAX development without knowing there was even a term for it ;-) The next day, one of my lunch pals asked me "hey, did you use that AJAX stuff to do that chat?"

    </story>

    Anyway, back to the actual topic: the AJAX chat sites I've seen have been fine. Chat with a desktop client may seem almost instantaneous, but it's really very much asynchronous, even with a desktop chat app. You type a message, hit send, and can immediately begin typing another message, whether or not the first message has been displayed on your friends screen, or even on your own (ever notice a lag with some IM clients between hitting send, and seeing your own message in the chat history part of the window? I have...)

    When I was developing my chat, I realized that the developer has a lot of control over how much lag the user could experience:

  • you can control how frequent the polls to the server are for new chat messages... in my case, a parameter to window.setInterval(), and whenever the user posted a new message
  • you can avoid redrawing the chat area if there are no updates
  • you can optimize things on the server to make each response get processed fast... mine was just for my friends and I, so I kept everything in memory (part of why it needed to be on a very stable host)
  • you can control how much content has to be transmitted with each update... in my case, I didn't bother to optimize this, and resent the entire chat history with each refresh

  • anyway, with the little bit of optimizations I did, the lag was less than we have sometimes noticed on Yahoo! IM or AIM.


    Tell me, what did you mean by "whenever someone types a message he/she has to wait for the response to come back" and "The problem is ofcourse asynchronous response"? The "asynchronous" part is the beauty of it - the user can be typing a new message, while in the background, the app periodically checks for and displays any new messages.... makes me think (after all this rambling) maybe I missed the point of your question...

    -- Jon
    [ April 04, 2006: Message edited by: Jon Egan ]
    16 years ago
    JSF
    Edisandro,

    You are getting different results because you are giving the two Hash implementations different object types...
  • in your first case, you give the HashMap instances of ToDos objects, for which the hashCode() contract is violated.... it doesn't agree with the equals() method notion of equality, as discussed above. HashMap is giving "incorrect" results because it is given "incorrect" objects to hash.
  • in your second case, you gave HashSet instances of String, for which hashCode() and equals() are perfectly well defined, and abide by the contract. HashSet is giving the "correct" result because it is given "correct" objects to hash.


  • Your example doesn't demonstrate an inconsistency between the hashing implementations of HashMap and HashSet (in fact, they are the same - a HashSet is backed by a HashMap - it just has null values). What you have demonstrated is the importance of adhering to the hashCode() contract if you want predictable results from HashMap, HashSet, etc.


    Try using the flawed object as the hashed item in your HashSet, and check the results:



    Hope this helps,
    -- Jon
    A few thoughts about the query execution time:

    1. It seems to me, only a really dumb DB engine should care that the index has a secondary column... the column specified in the WHERE clause is first in the index, which means the index (an ordered set of row pointers) is ordered first on that column, then (where the first column gives duplicates) on another column.

    2. If there are not an appreciable number of rows in the database, the engine may (rightly) not bother with the index.... it is sometimes faster to do a sequential table scan than to hop back and forth from a small index to a small table.

    3. The same point applies as in #2 if the database thinks there are not many rows in the table... in order for it to make an informed decision about the use (or not) of the index, it has to have up-to-date statistics. For Oracle, that means you need to analyze the table. For Informix, it's "update statistics". For MS SQL, it's probably control-F1-right-click-the-pretty-button.

    4. Sometimes, the "value in (val1, val2, val3)" can be enough to convince an engine to skip the index - I'm not clear as to why, if the list is small, the engine doesn't just translate it to the equivalent "(value = val1 or value = val2 or value = val3)", which has sometimes (anecdotaly) seemed to use an index when the IN clause has not.

    5. Some (most? I don't know...) DBs have an option that will give you some debugging info about how the DB engine will process the statement, along with an estimated "cost". The decision for a certain approach over another is based on the cost, and the cost is based on the accuracy of the statistics.... see #3.


    Then there's the other point, based on the original post:


    There is no difference in Query Execution Time for both queries.



    ... then, why are we all discussing query execution time?


    Business Logic Time is huge in second case as compared to first one (ratio - 1:20).
    Rows returned are more in first case as compared to second case.(ratio - 1:4)



    6. Unless the problem is truly in the business logic (whatever the real code is in place of STORE_ARRAY[x][y] = rs.getObject(i)), I can't see any reason why returning fewer rows should result in longer operation iterating through the ResultSet. If anything, the query execution time should differ, and the larger dataset should result in more "pages" from the DB, but the smaller should run faster in the java code. Can you verify that is really what you meant to say? That the smaller result set is actually taking 20 times as long to be processed in the java code?


    Hope any part of this helps...
    -- Jon
    Sounded like the OP was asking more about "why" someone would want to do such a thing.

    Just consider that it gives you extra flexibility.... you can have two classes of output - by default, they go to the same place, so you never need to differentiate.

    But, this feature allows you to separate them easily. Take this example:

    1. Write all your code that is printing errors using System.err, write all your code that gives informational messages using System.out.

    2. Go on and build an app that makes many, many calls to these two streams, in hundreds of places in the code.

    3. Five years (or three weeks) down the line, when you have 800 calls to System.out.println and System.err.println scattered throughout your code, then you get a requirement to monitor your app, and send a page any time an error message is generated.

    At this point, you can change all those calls to System.err.println.... or, you can start redirecting that output to a separate file, and set up something to monitor that file. Or, insert a new custom PrintWriter like in John's example, that sends the page AND writes to a file....

    The point is, you have a LOT of options, that you wouldn't have if all your messages were going to the same place.


    DISCLAIMER: I woud avoid using System.out and System.err in lots of places anyway..... put a wrapper method in some utility class, and call that from everywhere... make the argument list a custom bean of your own type, so you can change the parameters without changing all the calls... now, when you get a requirement to do something different with the output, you make the change in one place....


    Also, something else to keep in mind about System.out and System.err.... and I don't know whether this is accurate on every OS, development language, etc.... but they are not synchronized with each other, at least on some platforms. That means, if you write out a big block of text with one, then again with the other, the big blocks can show up intermingled in the output. That's enough to really mess with you when you're trying to read a stack trace....

    Hope this helps.
    -- Jon
    16 years ago
    Right, what I think Kevin is saying, and what I was getting at in my last post, is the kind of problems shown here. Once anything is assigned to an un-typed reference, no guarantees remain about the types:



    I was trying to convey a few different places where you coud lose the type, sorry if the examples got too jumbled.

    If there isn't any point where the Map is referenced without being typed, I don't know of any other reason why you would see that error.

    If there's more to the code that explains how "fieldMap" becomes "map", and you aren't sure it's ok, post again with more of the places it's touched/passed around/returned from a method call/stored.

    -- Jon
    [ February 21, 2006: Message edited by: Jon Egan ]
    Tim,

    Can you post the line(s) where you declare and instantiate the Map? Also, if you then pass the map to a method, show how you accept the Map parameter? You could have problems in all three of these areas, if all three are not specified with Generics.

    I don't have any theories outside this one, so I was hoping this would be it ;-)

    -- Jon
    Sounds like a job for the "body onlload" event handler we discussed earlier in the post... have the document.write() calls in a script, outside any function, so they are run as they are encountered. Then, have the function call that references the objects in the onlload event....

    if that doesn't work, maybe combine that with setTimeout()? meaning, have the onload event call functionA, which has only 1 line - a call to setTimeout(functionB, 2000), so the order of things is:

    page loads partially
    document.writes happen
    page loads more (maybe?)
    some objects created with document.write come into "existence" in the DOM
    page finishes loading
    functionA is called
    rest of objects created with document.write come into "existence" in the DOM
    functionB call is evaluated


    That's a real stretch though, not very clean code at all... what if someone else's browser takes 3000ms to evaluate those document.write()s?

    -- Jon
    Tim,

    I'm not able to test drive it right now to be sure, but it sounds like the problem might be that you haven't defined your map as I'd assumed. In order for the Map.keySet() method to return a Set<String> instead of Set (untyped), you need to define the Map as typed, something like I gave in the earlier post:



    Whatever the first item is in the Map type (shown in bold above) is the type of the Keys.... the other is the type of the Values. So, if you want the Keys to be known to be Strings, you have to define the Map as shown. If you don't know any common supertype for your Values, you can use Object.

    -- Jon