Database Programming with JDBC and JAVA by George Reese The unconfirmed errors are from readers. They have not yet been approved or disproved by the author or editor and represent solely the opinion of the reader. This page was last updated May 31, 2000. Unconfirmed errors: (31) There's a superfluous 'it' on page 31 at the bottom line. (36) The sentence begins with "switch gears now and talk ..." although the paragraph on page 35 ended with " ... you build a banking application." I would like to know how much text is missing between pages 35 and 36 because figure 3-7 isn't easy if you look at it for the first time. (37) In the first four lines, there is a repeated "3/00 edition" [39] In Figure 3-9 The banking application Object Model: It would be nice if all the diagrams in the book followed the UML notation. I just think that would be a nice touch, and it would automatically make the diagrams clearer - at least to those that know/understand UML notation. ?44? why not have a static DriverManager method (called, for example, "LoadDriver") instead of relying on a second-order side effect of "Class.forName(...)"? {53-54} In Example 4-3, a Connection object is created and set to null: Connection connection = null; Later in the example, the variable 'con' is used instead: con = DriverManager.getConnection (url, "borg", ""); There seems to be an inconsistency in the variable naming for this example. It looks like the same problem also appears in Example 4-4: one variable is declared (connection) and another variable (con) is used for the rest of the code. {63} (bottom) - the need for the implementation of the customer/account association was not explained in Chapter 3, perhaps it should be. {83} (example 6.1): the nature and use of the ID should be explained (with a brief example) before the source code example is presented. {95} listing the abstract methods of the "Persistent" class (i.e., those which must be overridden by a subclass) is useful and should be done for the other abstract classes as well (PersistentSet and Transaction). It would also be useful to indicate for each abstract class in what circumstances each method may need to be overridden. {96} the responsibilities of the different classes in fig. 6.5 is not clear (to me, at least), especially when comparing fig. 6.5 to fig. 6.3 on p. 81. {98} a note explaining how and when the static instance variable "url" should be set would be helpful, since this does not become evident until much later in the book. ?98? Example 6-3: This is more of a question than an error and I apologise if I'm being very dim! I am confused by the getTransaction method in the Transaction class which is defined as follows: static public Transaction getTransaction() throws PersistenceException { return new DatabaseTransaction(url, properties); } Surely this statically ties the Transcation into a DatabaseTransaction, in addition to this the DatabaseTransaction is a subclass of Transaction which seems odd to me. {104} (bottom): explain why PersistentSet does not need insert(), remove(), or update(). <105> the text states that the source code for the "Lock" class is in the reference section. I could not find it there. {117} shouldn't "customer.java" import "CustomerPeer.java" since it uses the CustomerPeer interface? [126]{126} Bottom of Page; This is actually an error in the code packaged with the book, rather than an error in the text itself. In the Lock.java file, in the LockThread class, there seems to be a synchronization bug. /* What happens if after lock.monitorLock() has been called (but before the following "if( commit )" line is executed), a modification is made to the Persistent object which is monitored, quickly followed by a call to commit(), which will will result in a call to lockThread.releaseLock()? In this case, lock.monitorLock() will never get a chance to notify Observers. I would propose that a "synchronized(this)" block be placed around the "lock.monitorLock(target);" line and the following "if( commit )" statement, so that a call to lockThread.releaseLock cannot occur between the execution of those two statements.*/ Here is the code of LockThread.run() as currently written: public void run() { try { int timeout = LockThread.TIMEOUT * 1000; while( true ) { ... lock.monitorLock(target); if( commit ) { stop(); break; } } } ... } Here is my proposed change: public void run() { try { int timeout = LockThread.TIMEOUT * 1000; while( true ) { ... synchronized(this) { lock.monitorLock(target); // releaseLock() might get called here, so must synchronize. if( commit ) { stop(); break; } } } } ... } {143} (bottom): should this be "ball =3D ..."? (compare p. 148, "server =3D ..."). {146} (Appserver class definition): "RemoteAppServer" has not been imported (or discussed). (152) paragraph 3: when the author mentions that the banking code needed to use "hashCode" to compare a remote object to a local object for equality, he should refer to the page(s) (e.g., p. 93) where this was done. {160} ("The Client"): the statement that "an object server can get remote objects served by any client that connects to it" seems to be more general than the previous statement on p. 149 to the effect that "a server cannot call a client which is behind a firewall". Perhaps "getting a remote object" is different from "calling a (remote) client", but some clarification would be helpful. {194} "The executeUpdate() statement" should read "The executeUpdate() method"