Enterprise JavaBeans, Third Edition by Richard Monson-Haefel This errata page lists errors outstanding in the most recent printing. If you have technical questions or error reports, you can send them to booktech@oreilly.com. (Please specify the printing date of your copy.) This page was last modified on January 9, 2004. Here's a key to the markup: [page-number]: serious technical mistake {page-number}: minor technical mistake : important language/formatting problem (page-number): language change or minor formatting problem ?page-number?: reader question or request for clarification Confirmed errors: (xiii) 2nd paragraph; it quickly become should be it quickly became (33) 2nd paragraph, 4th line; should be setMessageDrivenContext() instead of setMessageDrivenBeanContext() p.47 just below middle of page, jndiContext.lookup("java:comp/env/ejb/ReservationHome"); should be: jndiContext.lookup("java:comp/env/ejb/ReservationHomeRemote"); {49} Second paragraph; The onMessage() method is not defined in the MessageDrivenBean interface. It is defined in javax.jms.MessageListener. (65) last paragraph, first line; CHANGE: " processing of more then one " TO: "processing of more than one " (73) footnote; The footnote mentions "RemotePortableObject" instead of "PortableRemoteObject." (74) footnote marked with "cross"; The word "plugable" should be "pluggable." (75) 5th paragraph; CabinHomeRemote cabinHome = (CabinHome)PortableRemoteObject.narrow(ref, CabinHomeRemote.class); should be changed to : CabinHomeRemote cabinHome = (CabinHomeRemote)PortableRemoteObject.narrow(ref, CabinHomeRemote.class); (77) 2nd paragraph; CabinHomeRemote cabinHome = (CabinHome)PortableRemoteObject.narrow(ref, CabinHomeRemote.class); should be CabinHomeRemote cabinHome = (CabinHomeRemote)PortableRemoteObject.narrow(ref, CabinHomeRemote.class); (90) code: ejbCreate method; returns null; should be return null; (93) end of 1st paragraph of section "EJB 2.0 and 1.1: The callback methods"; The text "...it sets the name field." should read "...it sets the id field." (97) XML code segment; At the begining of the XML file: ... should be ... (98) 4th paragraph; CHANGE " (Cabin.class, CabinHome.class, CabinBean.class, and CabinPK.class) " TO: " (CabinRemote.class, CabinHomeRemote.class, and CabinBean.class) " {99} The class names in the figure do not match the class names in the text. remove CabinPK.class & CabinPK.java from figure change Cabin.class & Cabin.java to CabinRemote.class & CabinRemote.java in figure change CabinHome.class & CabinHome.java TO CabinHomeRemote.class and CabinHomeRemote.java [99] Figure 4-2; The "meta-inf" directory should be located under the "dev" directory, not the "cabin" directory. (106) middle of page; The definition of "getInitialContext" is misformatted so that the body statements are flush with the method definition immediately above (i.e., the 3 lines that make up the body are not indented). (114) Next to last paragraph last sentence; You EJB server's deployment tool ... Should be Your EJB server's deployment tool ... (115) code paragraph beginning; import com.titan.cabin.CabinHomeRemote import com.tian.cabin.CabinHomeRemote should be: import com.titan.travelagent.TravelAgentRemote; import com.titan.travelagent.TravelAgentHomeRemote; (118) 4th paragraph; "JNDI allows the application client to view the EJB server as a set of directories, like directories in a common filesystem." should be changed to "JNDI allows the application client to view the EJB server as a set of directories, like directories in a common file system." NOTE: The point is "filesystem" should be "file system" (two words) (119) 1st paragraph; "it's similar in concept to the root of a filesystem." should be changed to "it's similar in concept to the root of a file system." NOTE: The point is "filesystem" should be "file system" (two words) (121) first para; P. 120, para. 4 says: "To be compatible with Java RMI, the actual types used in the java.rimi.Remote interfaces must be primitives, String types, java.rmi.Remote types or serializable types. P. 121 para 1, which, if I understand correctly summarizes the previous 2 paragraphs, omits String types. AUTHOR: Here is how to fix this: (on page 120, paragraph 4) CHANGE: "be primitives, String types, java.rmi.Remote types, or serializable types. " TO: "be primitives, java.rmi.Remote types, or serializable types (including the String type). " (139) A little past half-way down the page; Integer pk_1 = new Integer(101) should be: Integer pk_1 = new Integer(100) (139) Last code fragment, 6th line; Shouldn't "Integer pk_1 = new Integer(101);" be "Integer pk_1 = new Integer(100);" as the remark is "Obtain cabin 100" in line 1? AUTHOR: CHANGE (page 139 code listing on lower half of page) Integer pk_1 = new Integer(101); TO: Integer pk_1 = new Integer(100); (143) 4th paragraph Line 7: "... rather then passed by reference". it should be: "... rather than passed by reference". At the end of the paragraph it says "passed by reference rather then copied" it should be "passed by reference rather than copied" (148) 3rd paragraph, 1st line.; "there is no need for network comminations." should be: "there is no need for network communication." (158) last complete sentence on page; "Although the return type of the ejbCreate() method is the primary key,..." should be: "Although the return type of the ejbCreate() method is the primary key type,..." [166] creating new Integer in both for-loops of Client.java; The Client.java-program contains a typo when creating the primary key. The sentence (java-code) should be changed from "Integer primaryKey = new Integer(args[i]);" to "Integer primaryKey = new Integer(i);" in both for-loops. The java-code would try to insert a record in the DB with a key equal to the argument passed from the command-line, which will fail because the argument passed will be a String even if the letter "1" was passed. AUTHOR: How to fix this: The following line occurs twice in the code listin on page 166. "Integer primaryKey =new Integer(args [ i ]);" CHANGE IT TO (replace args[ i ] with i): "Integer primaryKey =new Integer( i );" (170) line 2; This sentence has an unnecessary open-quote (before 'remote'): "We make dependant values immutable so that "remote clients cannot change..." remove extra open quote before remote (171) Line 7; The word "easy" on line 7 should be "easily" in the sentence that begins on line 6 and reads - "For example, we could easy add relationship fields for Phone, CreditCard, and other entity beans to the Customer EJB. [176] first paragraph, CustomerRemote example code; The setAddress(String street, String city, String state, String zip) method needs to throw RemoteException. (185) last sentence of second paragraph; In the last sentence of the 2nd paragraph, the word "separate" should be "separates" (187) 2nd paragraph; The last sentence you mis-typed Address EJB as Address EBJ {190} code segment; first line of the code: public class CustomerBean implements javax.ejb.EntityBean{ should be public abstract class CustomerBean implements javax.ejb.EntityBean{ it lost the "abstract" modifier. (194) code sample on bottom of page; The method "setCreditCard" should be renamed or commented to highlight the fact that it is a business method and not a persistence method even tho it has the same method name as the previously declared virtual method "setCreditCard". AUTHOR: MAKE THE FOLLOWING CHANGE: CHANGE (add the comment to last code listing on page 194): public abstract class CustomerBean implements javax.ejb.EntityBean { ... public void setCreditCard(Date exp, String numb, String name, String org) TO: public abstract class CustomerBean implements javax.ejb.EntityBean { ... // The setCreditCard() business method uses the setCreditCard() abstract accessor. public void setCreditCard(Date exp, String numb, String name, String org) (199) code at bottom of page; line of code: if(phone.getType() = typeToRemove) { SHould be: if(phone.getType() == typeToRemove) { (199) Last line of code on page; java.util.Iterator does not contain the method: remove(Object o) The removePhoneNumber(byte typeToRemove) method attempts to remove an object from the iterator using iterator.remove(phone); The line should read phoneNumbers.remove(phone); The code that is downloadable is correct. AUTHOR: MAKE THE FOLLOWING CHANGE (to last code listing on page 199) CHANGE: iterator.remove(phone); TO: iterator.remove(); [200] CHANGE figure 7-7 In addition to the arrow drawn from CustomerA to Phone1, Arrows should also be drawn from the CustomerA to Phone2 and Phone3. (200) code at top of page; line of code: if(phone.getType() = typeToUpdate) { Should be: if(phone.getType() == typeToUpdate) { {200} Figure 7-7 On pg 200, should the 2nd diagram indicate one or three arrows removed? See attached image (figure 7-7 MODIFIED) for change (213) Figure 7-15; reservationsB.saddALL(...) should be reservationsB.addALL(...) See figure 7-15 MODIFIED in attached. (215) 3rd paragraph; Missing word in sentence: Many-to-many bidirectional relationships always require a link [table] in a normalized relational database. [234] 1st paragraph CHANGE: "The name given in each must match one of the ejbSelect methods defined in the bean class" TO: "The name given in each element must match one of the ejbSelect methods defined in the bean class" (247) Second sentence of the third paragraph; "...produces in an UNKNOWN result" should be "...produces an UNKNOWN result" (295) last paragraph on page; The sentence reading "... so assignment of relationships is postponed until ejbPostCreate() completes and the primary key become available." should read "...so assignment of relationships is postponed until ejbCreate() completes and the primary key becomes available." (366) The first large paragraph under heading "TopicConnection and Topic Session" ; The sentence "However, having more than one TopicSession object is frequently helpful; if you wish to produce and consume messages using multithreading, a different Session needs to be created by each thread accessing that thread" should end with the word "Topic" rather than "thread". AUTHOR: The reader is kind of right. I would add this to the confirmed errata with the following change: (366) CHANGE: " each thread accessing that thread." TO: " each thread."