Enterprise JavaBeans 3.0, Fifth Edition by Richard Monson-Haefel, Bill Burke The unconfirmed error reports are from readers. They have not yet been approved or disproved by the author or editor and represent solely the opinion of the reader. 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 This page was updated June 12, 2008. UNCONFIRMED errors and comments from readers: {example code} example code; Examples import javax.annotation.EJB That has moved to javax.ejb.EJB (at least with one of the later java 5 sdk I am using). (xxii) Line below "Chapter 18,..."; The line reads as follows: "This chapter explains the XML, SOAP, WSLD and UDDI web services standards." WSLD => WSDL {24} Bottom of page, setCustomer() method; entityManager.create(cust) should be entityManager.persist(cust) {28} Code example; entityManager.create(reservation); should be entityManager.persist(reservation); {54} First paragraph; "The element represents the set of classes" ... should describe the name attribute, not element; is not an element in the XML appearing above the text (on the previous page), it's an attribute on the persistence-unit element. [57] Figure 4-2; The titan.jar content is wrong. It should contain TravelAgentBean.class instead of TravelAgentBean.java. Also META-INF/persistence.xml (and MANIFEST.MF) is missing in the diagram. {57} Figure 4-2; There is no "dev" directory of titan.jar, so the first box should be removed or renamed to "/" (the root of the file). Also, a box with the name "META-INF" should be added to the root folder and list the file "persistence.xml" as contents. {60} second-to-last paragraph; p. 58: Object ref = jndiContext.lookup("TravelAgentBean/remote"); TravelAgentRemote dao = (TravelAgentRemote) PortableRemoteObject.narrow(ref,TravelAgentRemote.class); p. 60: Object ref = jndiContext.lookup("TravelAgentRemote"); CabinHomeRemote home = (TravelAgentRemote) PortableRemoteObject.narrow(ref,TravelAgentRemote.class); Not sure about this, but I think the "CabinHomeRemote" interface on page 60 is left over from an earlier edition of the book (and EJB spec). I think it should be "TravelAgentRemote", as it is on page 58. {60} Code snippet near bottom of page; Object ref = jndiContext.lookup("TravelAgentRemote"); should be: Object ref = jndiContext.lookup("TravelAgentBean/remote"); {68} Figure 5-1; There is no "dev" directory of titan-persistence.jar, so the first box should be removed or renamed to "/" (the root of the file). [69] 4rd paragraph, mid-page; javax.persistence.PersistenceProvider must be javax.persistence.spi.PersistenceProvider (76) 2nd code example; Custom cust = new Customer(); should be Customer cust = new Customer(); {77} top paragraph; the second sentence, "TransactionRequiredException is thrown if this method is invoked on a transaction-scoped persistence context." should be "TransactionRequiredException is thrown if this method is NOT invoked on a transaction-scoped persistence context." (77) 5th paragraph, above last code example; Replace colon with a period at the end of the sentence "So, the constant 2 is converted to a java.lang.Integer:" This sentence refers to the code above the paragraph, not below. (77) 2nd to last paragraph; The sentence "and there is no guarantee that the entity's state will be initialized" doesn't make sense. If the javax.persistence.EntityNotFoundException exception is thrown, the entity doesn't exist, hence you cannot speak of its state. The value of the cust variable will still be null. {78} 4th paragraph; There hasn't been introduced any methods named "getResource()", so what the author probably means is the "getReference()" method of the entity manager. [79] Second paragraph; It's stated that "the persistence context ends when the findCabin() method finishes, as it is a single JTA transaction". There is no guarantee that this is the case since the @TransactionAttribute is "REQUIRED". The method will join any JTA transaction running when the method is invoked. The statement will only be true if the @TransactionAttribute has the value "REQUIRES_NEW" in which case a new JTA transaction is started when the method is invoked. {80} 2nd paragraph, 2nd sentence; Should be "The TransactionRequiredException is thrown if this method is NOT invoked on a transaction-scoped persistence context." (81) Top of page first line; "removeCabin(int id)" is probably meant to be "refreshCabin(int id)" {81} 2nd paragraph, 2nd sentence; Should be "The TransactionRequiredException is thrown if this method is NOT invoked on a transaction-scoped persistence context." [82] Bottom of page; The getTransaction() method is not listed on page 75-76. {90} Second paragraph; Change: "We also want firstName to have a not-null contraint" To: "We also want firstName and lastName to have a not-null contraint". {100} Middle of page in XML; doesn't use embedded text to set the class name. It uses the class attribute instead. So instead of com.titan.domain.CustomerPK it should read {102} Middle of page - code for Customer class; public PK getPk()... should be public CustomerPK getPk()... {103} Top of page - @AttributeOverrides code; There is probably a ")" missing in @AttributeOverride(name="lastName"....LAST_NAME"), before the comma (103) Middle of page - line above xml listing; Let us now look at .... @IdClass: should probably read Let us now look at .... @EmbeddedId: {104} Bottom of page - code example; public PK getPk()... should probably read public CustomerPK getPk()... [112] Second Paragraph; "The @PrimaryKeyJoinColumn specifies the column in the ADDRESS_TABLE that you will join with the primary key of the CUSTOMER_TABLE . In this case, it is ADDRESS_ID. We do not need to specify the referencedColumnName( ) attribute of this annotation because it can default to the Customer entity's primary-key column." This paragraph seems to contradict with the first paragraph above it. 1. "join with the primary key of the CUSTOMER_TABLE" ? We are trying to get address, what does it have to do with the primary key of the CUSTOMER_TABLE? 2. "it can default to the Customer entity's primary-key column"? see 1) [114] Last paragraph; The paragraph states that "The embedded Address class has the @Column mappings defined directly within it." This is obviously not the case when looking at the code. The JBoss example in the "JBoss Workbook" later has the annotations though. [115] bottom - xml mapping; embeddable class description doesn't have list of attributes. embeddable element has wrong attribute tag "access-type" - should be "access". embeddable element should be listed at the end of the xml. {120} Top of page - Customer entity code listing; private Address address; should be private Address homeAddress; for the get/set functions to work. {121} Bottom of page - xml listing; ALL should be {127} Java code at end of page; In the method getCreditCard(), "return homeAddress;" should be "return creditCard;". [129] First paragraph; I believe the use a foreign-key column to implement a one-to-many unidirectional relationship is not required by JPA 1 (i.e it's a vendor extension). It doesn't work on Toplink Essentials -- a join table seems to be required. {129} Figure 7.5; PHONE table foreign key should be CUSTOMER_ID rather than CREDIT_CARD_ID {133} one-to-many element in Xml at bottom of page; attribute targetEntity should be target-entity. {133} top of page - customer entity code listing; @JoinTable(name="CUSTOMER_PHONE"), should be @JoinTable(name="CUSTOMER_PHONE", {137} Code snippets and text; The code snippets and text on this and other pages throughout the book refer to a user-provided no-arg constructor as the "default constructor". This is wrong as the Java Language Specification describes the default constructor as the (no argument) constructor automatically provided if the class does not contain any (user-provided) constructors. I suggest reviewing the text (and code samples) and replacing "default constructor" and "default no-arg constructor" with "no-arg constructor" as appropriate. {141} First code sample; The "date" property should be annotated with the @Temporal(TemporalType.DATE) annotation. {142} middle of page - cruise entity xml listing; customers)" and have a method body like "{ this.customers = customers; }". {146} top of page - customer entity xml listing; should read as Map two occurrences [148] in unconfirmed errata; I disagree with the unconfirmed errata. Set is correct in its usage. Set is used for the reason described on page 144 second to last paragraph (for Reservation's collection of Customers). (151) middle of page - reservation entity code listing; public void setCustomers(Set Customers); should not have semicolon - as this line is probably part of function definition and not a declaration {151} Middle of page; The method "public void setCustomers(Set customers);" should be changed to "public void setCustomers(Set customers)". A current correction has already stated that the method should have a method body like on p144. {151} code example, middle of page (same place as previous errata); should setCustomers(Set customers) be setCustomers(List customers) or should the text explain why set it being used This is the first example of a List-based collection. [153] Bottom of page; According to the EJB3 specification, FetchType.LAZY is only a hint and may not be honored by the persistence provider, therefore the relationship may be eagerly fetched. {154} bottom code example; Customer cust is defined but Customer customer is used instead. "customer.setAddress(new Address());" should be "cust.setAddress(new Address());" "customer.setPhoneNumbers().add(new Phone());" should be "cust.setPhoneNumbers().add(new Phone());" {161} code example, middle of page; declaration needs opening brace public @interface DiscriminatorColumn public @interface DiscriminatorColumn { {168} middle of page - Customer entity listing; @AttributeOverride(name="lastname",... should be @AttributeOverride(name="lastName",... {171} Code sample, bottom of page; entityManager.creatQuery( should be entityManager.createQuery( (171) last codeblock; The query "from Customer c" is incorrect. It is correct Hibernate hql, not correct jpql/ejbql. Correct syntax it "select c from Customer c". Identical error also appears in the last codeblock on page 172 and the first one on page 173. [172] first paragraph line 4 ; I have noticed a typo in this book at page number 172 in chapter 9. It says Query#getSingleResult() throws javax.persistence.EntityNotFoundException If no result returned. But this is not true, Query.getSingleResult() throws javax.persistence.NoResultException if there is no result. This is as per the Docs given by Sun. {172} 3rd paragraph; In the first line of the first code example on page 172 it should read "Query query = entityManager.createQuery(" instead of "Query query = entityManager.creatQuery(" . [172] 1st paragraph; 3rd & 4th line: If no result is returned then javax.persistence.NoResultException is thrown, not EntityNotFoundException, as described in the book. The code excerpt on previous page also contains the same logical error Found on testing with JBOSS 4.2.GA {184} top of page - section "Using DISTINCT"; SELECT res FROM ... should be SELECT cust FROM ... {185} Third-to-last paragraph; Change "Reservation EJBs" to "Reservation entities". {194} Third paragraph; The paragraph mentions CMR fields and CMP fields which don't exist in EJB3. {195} Middle of page; In the code example, replace "SELECT DISTINCT COUNT(c.address.zip)" with "SELECT COUNT(DISTINCT c.address.zip)". {200} middle of page; Section: EXISTS; query listing; ...(SELECT res FROM cr.reservations WHERE ... should be ...(SELECT res FROM cr.reservations res WHERE ... {203} Middle of page; XML listing; should be {203} Bottom of page; Java example; @SqlResultSetMapping(name="reservationCount", entities=@EntityResult(name="com.titan.domain.Cruise", fields=@FieldResult(name="id",column="id")), columns=@ColumnResult(name="resCount")) should be @SqlResultSetMapping(name="reservationCount", entities={@EntityResult(entityClass=Cruise.class, fields={@FieldResult(name="id",column="id")})}, columns={@ColumnResult(name="resCount")}) (205) Top of page query example; FROM Cruise As c, JOIN c.reservations r comma may be extra - should be FROM Cruise As c JOIN c.reservations r {206} Bottom of page; XML listing; result-set-mapping="customerAndCCNumMapping"/> should be result-set-mapping="customerAndCCNumMapping"> {205} Middle of page; Change Query.setParameter("cruise", cruise); to query.setParameter("cruise", cruise); {209} Bottom, Code; afterInsert() should read as beforeInsert() {210} Bottom; beforeInsert() should read as afterInsert() (218pp) Headline starting "Domain objects"; The book uses the term "domain object" to denote types of objects that typically are "transfer objects" (or in some cases possibly "value objects") in the sense of Patterns of Enterprise Applications (Fowler). While I understand the desire to avoid terms that are too close to "data transfer object" as used in EJB 2.x contexts, I believe that the choice of "domain object" is unfortunate in this case. The EJB 3.0 spec states: "An entity is a lightweight persistent domain object." However, the author uses the term to refer to a non-persistent object. This might be confusing to the non-expert reader. Therefore, I suggest changing the terminology in future versions of the book. (220) Middle of page; Add the word "annotation" after "@javax.ejb.ApplicationException". (222) Middle of page; In the code sample, change "Package javax.ejb;" to "package javax.ejb;" {222} Third paragraph; Change: The EJB name defaults to the unqualified name of the bean class if you initialize this attribute. To: The EJB name defaults to the unqualified name of the bean class if you don't specify this attribute. {225} Top of page xml listing; In the xml listing on pages 224 and 225, the "env-entry" should be specified before "resource-ref" (jboss rejects it as listed). [225] xml-file; There is an errata that says: '{225} Top of page xml listing; In the xml listing on pages 224 and 225, the "env-entry" should be specified before "resource-ref" (jboss rejects it as listed).' But that is wrong. Still, I cannot get JBoss to use this file in the correct manner. Both the 'datasource' and the 'min' are not valid. (226) bottom code snippet; The camel notation for the veriable myself is spelled "mySelf" implying myself is actually two words, which it is not. {227} Middle of page; In the code sample, the last two lines should be changed from: public EJBHome getEJBHome() java.lang.IllegalStateException; public EJBLocalHome getEJBLocalHome() java.lang.IllegalStateException; to public EJBHome getEJBHome() throws java.lang.IllegalStateException; public EJBLocalHome getEJBLocalHome() throws java.lang.IllegalStateException; [251] Bottom, Code; ticketDescription should read as ticket.discription [253] Bottom, Code; ticketDescription should read as ticket.discription {254} Top of page; In the first code sample, change: mapMsg.setInt("CustomerID", ticket.customerID.intValue()); mapMsg.setInt("CruiseID", ticket.cruiseID.intValue()); mapMsg.setInt("CabinID", ticket.cabinID.intValue()); to mapMsg.setInt("CustomerID", ticket.customerID); mapMsg.setInt("CruiseID", ticket.cruiseID); mapMsg.setInt("CabinID", ticket.cabinID); (254) Middle of page, objectMsg example; The lines ObjectMsg.setObject(ticket); producer.send(mapMsg); should probably be objectMsg.setObject(ticket); producer.send(objectMsg); (256) Top of page; Change: env.put(Context.INITIAL_CONTEXT_FACTORY, " org.jboss.security.jndi.JndiLoginInitialContextFactory"); To: "org.jboss.security.jndi.JndiLoginInitialContextFactory"); (262) Top of page; Change "A message-driven bean is a complete enterprise bean, just like a session or entity bean," to "A message-driven bean is a complete enterprise bean, just like a session bean,". EJB3 has no concept of entity beans. (262) Middle of page; Change "it creates a new Reservation EJB" to "it creates a new Reservation entity". (263) code fragment; The @ActivationConfigProperty(propertyName="destination", propertyValue="queue/titan- ReservationQueue") sub-annotation is missing. This annotation is required. Error repeats on page (268). [264] Bottom of page; The listing showing EJBContext doesn't correspond to the listing on page 227. {265} Middle of page; Change "javax.jta.UserTransaction" to "javax.transaction.UserTransaction". [269] 4th Paragraph; The statement "all fields that are nontransient and nonserializable must be set to null before the instance is passivated..." should be "all fields that are transient and nonserializable must be set to null before the instance is passivated..." {272} Top of page xml listing; There seem to be a lot of mistakes with the xml listing: 1. line 7: should by 2. line 18: should be 2. lines 20,21: should be should be should be connectionFactory instead of datasource {283} Middle of page; XML listing; should be com.titan.travelagent.TravelAgentBean and not javax.jms.Topic [287] Bottom, Code; implements ShipMaintenanceRemote implements javax.ejb.TimedObject should read as implements ShipMaintenanceRemote, javax.ejb.TimedObject {287} Bottom of page; In the second code sample, replace the second occurrence of "implements" with a comma. {287} Bottom of page; Replace "implement" with "implements" {288} Middle of page; Change ShipMaintenanceRemote maintenance = (ShipMaintenanceRemote) jndiCntxt.lookup("ShipMaintenanceRemote "); ShipMaintenanceRemote Calendar april2nd = Calendar.getInstance(); to ShipMaintenanceRemote maintenance = (ShipMaintenanceRemote) jndiCntxt.lookup("ShipMaintenanceRemote"); Calendar april2nd = Calendar.getInstance(); {288} 4th line from bottom of the page; 3rd parameter of scheduleMaintenance method, Date dateOfTest should be Date dateOf {288} Bottom of page; Remove non-relevant "@PersistenceContext(unitName="titanDB") entityManager;" {288} Bottom of page; Change: String item = ship + " is scheduling maintenance of " + description; To: String msg = ship + " is scheduling maintenance of " + description; {289} middle of page code listing; line: @Resource(mappedName="MaintenanceTopic") topic; should be @Resource(mappedName="MaintenanceTopic") Topic topic; {289} 3rd parameter of scheduleMaintenance method; Date dateOfTest should be Date dateOf [292] First paragraph; Replace the paragraph After getting a reference to the TimerService, we get a Collection that contains all of the Timers. Then we loop through the Collection, canceling each timer whose MaintenanceItem is the desired ship. with After getting a reference to the TimerService, we get a Collection that contains all of the Timers for the ShipMaintenanceBean EJB. Then we loop through the Collection, canceling each timer. {294} Middle of page; Replace the paragraph "The scheduleMaintenance() method first obtains a Collection of all timers defined for the ship." to "The scheduleMaintenance() method first obtains a Collection of all timers defined for the ShipMaintenanceBean." {295} Bottom of page; replace: Timer.cancel(); with: timer.cancel(); [295] Bottom, Code; javax.ejb.Timer timer = (javax.ejb.Timer) obj; is missing in for loop {296} The section "Retrieving other information from timers"; Contrary to the contents of the section, the Timer.getNextTimeout() method always returns a java.util.Date representing the time at which the timer expires next, and Timer.getTimeRemaining() returns the interval until expiration. In other words, the text "If, however, the timer is an interval timer, the Date returned is the time remaining until the next expiration." should be removed. (296) Middle of page; The javax.ejb.Handle and javax.ejb.HomeHandle are not discussed in chapter 5. {296} Bottom of page; Replace "javax.ejb.NoSuchObjectException" with "javax.ejb.NoSuchLocalObjectException". {298} 3rd line from bottom; @PostCreate should be @PostConstruct {299} 1st line; @PostCreate should be @PostConstruct (299) last line of 2nd paragraph; using "@PreDestroy method..." may be mora appropriate than "ejbRemove() method..." (299 & 301) Figures 13.1 and 13.2; Figures 13.1 and 13.2 are the same. Is it right? {305} 1st paragraph; "enterprise naming context" should be "environment naming context" (as per Java EE 5 and EJB 3 specs). This mistake is found throughout the book. However, the correct name is given in a few instances. {305} 2nd paragraph (also on other pages / paragraphs); @javax.annotation.EJB must be @javax.ejb.EJB {306} 2nd paragraph; The given xml code for the ejb-jar.xml is not valid. The tag is not closed. (308) paragraph after first code segment; "You do not append the 'java:comp/env' string to the name..." you would never *append* it; it normally is prefixed to the lookup name in this case you do not *prepend* the sub-string (though not in most dictionaries, 'prepend' is a word all computer scientists know) {309} last paragraph (xml listing); The xml tag is opened but the xml tag is closed. This is not valid xml. [315] XML-based remote EJB references XML snippet; The opening tag misses a closing tag [316] Last XML snippet on page folding to next page; Opening tag misses a closing tag. [317] Second XML snippet on page; Opening tag misses a closing tag. [317] Middle of page; Remove the word "remote" from the paragraph "The defines a reference to remote EJBs." [317] Middle of page; Change: ejb/ProcessPaymentRemote To: ejb/ProcessPaymentLocal [317] Bottom of page; Change "The element can have one of two values, Session or Entity, according to whether it is a session bean or an EJB 2.1 entity bean home interface." to "The element can have one of two values, Session or Entity, according to whether it is a session bean or an EJB 2.1 entity bean local home interface." [317] Bottom of page; Change "..., then the element must be provided with the fully qualified name of the bean's home interface." to "..., then the element must be provided with the fully qualified name of the bean's local home interface." [317] last; The element can be ... should be The element can be ... {318} Middle of page; Change ProcessPaymentLocal local = (ProcessPaymentRemote) jndiContext.lookup("java:comp/env/ejb/ProcessPaymentLocal"); to ProcessPaymentLocal local = (ProcessPaymentLocal) jndiContext.lookup("java:comp/env/ejb/ProcessPaymentLocal"); [318] Last XML snippet on page; Opening tag misses a closing tag. {319} Middle of page; Replace "inventory.jar" with "inventory-ejb.jar". [322] First XML snippet; Opening tag misses a closing tag. {325} Top of page; In the code sample, replace EntityManager titan = (EntityManagerFactory) jndiContext.lookup("java:comp/env/ejb/persistence/TitanDB"); with EntityManager titan = (EntityManager) jndiContext.lookup("java:comp/env/ejb/persistence/TitanDB"); {326} Middle of page; Add missing "" closing element to XML. {329} Top of page; Change: type=javax.sql.DataSource, To: type=javax.sql.DataSource.class, {329} Bottom of page; Change: type=javax.sql.DataSource, To: type=javax.sql.DataSource.class, [331] First XML snippet; Opening tag misses a closing tag. [332] First XML snippet; Opening tag misses a closing tag. [333] All XML snippets; Opening tag misses a closing tag. [334] First XML snippet; Opening tag misses a closing tag. [335] First XML snippet; Opening tag misses a closing tag. {336} Middle of page; Change: type=javax.jms.Topic, To: type=javax.jms.Topic.class, [337] First XML snippet; Opening tag misses a closing tag. (341) bottom of page InvocationContext listing; The JBOSS API InvocationContext seems to contain a "getBean" method and not a "getTarget". I suppose in this case the book is right and it may be a JBOSS issue? {347} audit() method in code; the method should return a value, likely, it should end with: return returnValue; {350} last code snippet; the custom annotation (from the previous code block, and used in the following page) is named 'JndiIndected'. the annotation used here is '@JndiInject', text should read: @JndiInjected("java:/TransactionManager") (352) Top of page; Change "customer" to "custom". {388} Top of page; Change: "javax.ejb.TransactionManagementType of Bean using the @javax.ejb.TransactionManager annotation" To: "javax.ejb.TransactionManagementType of BEAN using the @javax.ejb.TransactionManagement annotation". {388} Middle of page; Change: @TransactionManagement(TransactionManagerType.BEAN) To: @TransactionManagement(TransactionManagementType.BEAN) [399] Bottom of page; The paragraph "The IncompleteConversationalState exception is thrown if one of the arguments passed into the bookPassage() is null." should be changed to "The IncompleteConversationalState exception is thrown if one of the (previously set) properties customer, cruise or cabin is null." (See page 241 for definition of the method). ?406? Conversational Persistence Contexts; This works on Hibernates EntityManager, but not on TopLinks EntityManager. The question is whether this is required by the specifications. (I couldn't find it) (407) Top, Source; customer0 must be customer (411) Bottom, Source; customer0 must be customer {416} Bottom of page; In the code sample, replace: @RolesAllowed("AUTOHORIZED_TRAVEL_AGENT") with: @RolesAllowed("AUTOHORIZED_MERCHANT") {417} 1st paragraph; The AUTHORIZED_MERCHANT role seems to be called AUTHORIZED_TRAVEL_AGENT in the preceding text and (annotation-based) example. This causes annotation-related text and example to be inconsistent with the XML-related text and example. {418} Top of page; Change: byCheck To: byCash {420} Top of page; In the XML fragment, change double[] to double[] {422} Middle of page; Change: To: {422-423} Java code at bottom of p. 422; Java code at center of p. 423; Page 422: javax.security.Principal getCallerPrincipal(); should be java.security.Principal getCallerPrincipal(); {423}: import javax.security.Principal; should be import java.security.Principal; [exercise19_1] build.xml target name="run.client"; the system property "java.endorsed.dirs" has to be set into the run.client target of build.xml for ex19_1 and other related examples like below, otherwise the client will run in a unmarshalling error: {455} Table 19-1; In the second column, change Byte Boolean Short Int Long float Double to byte boolean short int long float double It's explained in the following paragraph when it is the object wrapper classes that are used. {456} Middle of page; Change: The address attribute To: The location attribute (or change to "The element"). {457 & 475} Listing; Seems that there is something wrong with the listing. Two EntityManagers with the same variable name "em" are declared. One @PersistenceContext(unitname="titanDB") private EntityManager em; and one @PersistenceContext EntityManager em; {473} Code Sample (2nd ProcessorService constructor); The constructor for the javax.xml.ws.Service does not take a String, but a URL object. [494] Figure 21-2; The figure is completely wrong if it's to illustrate the concepts introduced on p. 492-493. The relation between Cruise and Reservation should have "0..*" multiplicity on the Reservation side. The relation between Cruise and Ship should have "0..*" multiplicity on the Cruise side. The relation between Ship and Cabin should have "0..*" multiplicity on the Cabin side. The relation between Cabin and Reservation should have "0..*" multiplicity on the Cabin side. {499} Figure 21-4; The TravelAgent and Customer diagrams should have "<>" added to them. Remove the arrow between the TravelAgent and the Customer entities. {502} Figure 21-5; Same corrections as in figure 21-4. {503} Figure 21-6; Same arrow correction as in figure 21-4. [503] Figure 21-7; The figure doesn't show the current customer as a method parameter. Instead it shows the current customer as a property like it's a Stateful EJB. The figure should show a Stateless EJB. {536} "section next to trail icon; http://jakarta.apache.org/ant must be http://ant.apache.org {541} persistence.xml code; titan should be: {542} Middle of page; In the JBoss example available for download, the PortableRemoteObject.narrow() has been removed. This also applies to many other examples that are inconsistent. {562} Bottom of page; Change: To: {567} Bottom of page; Add the following method: public void setTimeCreated(Date date) { timeCreated = date; } {572} Middle of page - code listing Customer.java; public PK getPk()... should probably read public CustomerPK getPk()... (597) middle of page - Excercise 8.2 heading; Heading should be "Single Table per [Concrete] Class" and not "Single Table per Hierarchy" [620] last paragraph; "FROM Cruise cr WHERE NOT EXISTS (SELECT res.amountPaid from cr.reservations res WHERE res.amountPaid = 0)" gets "All cruises that have down payments" instead of "Cruises that have reservations that don't have a down payment" {666} Section "Start Up JBoss"; Start Up JBoss must refer to Workbook 1 instead of Chapter 15 [684] This page and the following related to the client; I am trying to run Exercise 19. "Exposing a Stateless Bean" with JBoss 4.2.1 GA and JDK 1.6.0_01. First, the generated WSDL location is not http://localhost:8080/titan/TravelAgentBean?wsdl but http://localhost:8080/TravelAgentBeanService/TravelAgentBean?wsdl After I made this change in config files I have the following while running "ant run.client" run.client: [java] javax.naming.NamingException: Could not dereference object [Root exc eption is org.jboss.ws.WSException: Cannot obtain java type mapping for: {http:/ /travelagent.titan.com/}createCabin] [java] at org.jnp.interfaces.NamingContext.getObjectInstanceWrapFailure (NamingContext.java:1152) [java] at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:70 7) [java] at org.jboss.naming.client.java.javaURLContextFactory$EncContext Proxy.invoke(javaURLContextFactory.java:135) [java] at $Proxy0.lookup(Unknown Source) [java] at javax.naming.InitialContext.lookup(InitialContext.java:392) [java] at com.titan.clients.Client.main(Client.java:19) [java] Caused by: org.jboss.ws.WSException: Cannot obtain java type mapping for: {http://travelagent.titan.com/}createCabin [java] at org.jboss.ws.metadata.builder.jaxrpc.JAXRPCMetaDataBuilder.pr ocessDocElement(JAXRPCMetaDataBuilder.java:627) [java] at org.jboss.ws.metadata.builder.jaxrpc.JAXRPCMetaDataBuilder.bu ildParameterMetaDataDoc(JAXRPCMetaDataBuilder.java:886) [java] at org.jboss.ws.metadata.builder.jaxrpc.JAXRPCMetaDataBuilder.se tupOperationsFromWSDL(JAXRPCMetaDataBuilder.java:214) [java] at org.jboss.ws.metadata.builder.jaxrpc.JAXRPCClientMetaDataBuil der.buildMetaDataInternal(JAXRPCClientMetaDataBuilder.java:216) [java] at org.jboss.ws.metadata.builder.jaxrpc.JAXRPCClientMetaDataBuil der.buildMetaData(JAXRPCClientMetaDataBuilder.java:133) [java] at org.jboss.ws.core.jaxrpc.client.ServiceImpl.(ServiceImp l.java:126) [java] at org.jboss.ws.core.jaxrpc.client.ServiceObjectFactory.getObjec tInstance(ServiceObjectFactory.java:141) [java] at javax.naming.spi.NamingManager.getObjectInstance(NamingManage r.java:304) [java] at org.jnp.interfaces.NamingContext.getObjectInstance(NamingCont ext.java:1127) [java] at org.jnp.interfaces.NamingContext.getObjectInstanceWrapFailure (NamingContext.java:1144) [java] ... 5 more {695} last parapgraph (not tip); "$JBOSS_HOME/service/default/deploy" should be "$JBOSS_HOME/server/default/deploy" (711) Index, under H; The index includes an entry for " element, 315, 316", which is presumably left from a previous edition. Doesn't seem to exist on those pages. Also, on page 726, there's an entry for "setFactory2", which seems pretty useless as it's just an example of how to inject a 2nd entity manager factory. [exercise19_1] build.xml target name="run.client"; the system property "java.endorsed.dirs" has to be set into the run.client target of build.xml for ex19_1 and other related examples like below, otherwise the client will run in a unmarshalling error: