Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999...

470
SG24-5258-00 International Technical Support Organization http://www.redbooks.ibm.com Using VisualAge Smalltalk ObjectExtender Markus Muetschard, Marianne Schmid, Bernd Kaponig, David Singleton

Transcript of Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999...

Page 1: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

SG24-5258-00

International Technical Support Organization

http://www.redbooks.ibm.com

Using VisualAge Smalltalk ObjectExtender

Markus Muetschard, Marianne Schmid, Bernd Kaponig, David Singleton

Page 2: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization
Page 3: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Using VisualAge Smalltalk ObjectExtender

February 1999

SG24-5258-00

International Technical Support Organization

Page 4: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

© Copyright International Business Machines Corporation 1999. All rights reservedNote to U.S Government Users – Documentation related to restricted rights – Use, duplication or disclosure is subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corp.

First Edition (February 1999)

This edition applies to the IBM VisualAge Smalltalk ObjectExtender Feature Version 4.5a of the IBM VisualAge Smalltalk Enterprise Version 4.5a product family.

Comments may be addressed to:IBM Corporation, International Technical Support OrganizationDept. QXXE Building 80-E2650 Harry RoadSan Jose, California 95120-6099

When you send information to IBM, you grant IBM a non-exclusive right to use or distribute the information in any way it believes appropriate without incurring any obligation to you.

Before using this information and the product it supports, be sure to read the general information in Appendix G, “Special Notices” on page 407.

Take Note!

The code for the samples in this book is available as SG245258.zip on:

. ftp://www.redbooks.ibm.com/redbooks/SG245258

Download and unzip the sg245258.zip file and read the aaRead.txt file.

Sample Code on the Internet!

Page 5: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Contents

Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xi

Tables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii

Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .xxiHow the Book Is Organized . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiThe Team That Wrote This Redbook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiiComments Welcome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii

Part 1. Introductory Tour . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

Chapter 1. Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.1 Application Layers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51.2 Persistence Layers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

1.2.1 Business Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.2.2 Schemas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81.2.3 Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

1.3 Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111.3.1 Shared Transaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111.3.2 Top-Level Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121.3.3 Nested Transactions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121.3.4 Transacted Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

1.4 Frameworks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141.5 Data Abstractions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

1.5.1 Model Metadata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151.5.2 Application Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151.5.3 Application Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

1.6 Metadata and Its Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

Chapter 2. Development Paths . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

© Copyright IBM Corp. 1999 iii

2.1 Forward or Top-Down: Start with the Object Model . . . . . . . . . . . . . . 192.2 Backward or Bottom-Up: Start with the Database . . . . . . . . . . . . . . . . 202.3 Outside-In: Map the Model to the Database Schema . . . . . . . . . . . . . 222.4 Whatever YOU Like . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

Chapter 3. Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233.1 Browsers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

3.1.1 Model Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243.1.2 Schema Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273.1.3 Map Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323.1.4 Status Browser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

Page 6: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

3.2 System Transcript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363.3 Smalltalk Class Editor and VisualAge Script Editor . . . . . . . . . . . . . . . 373.4 Inspectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

Chapter 4. Sample Scenarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414.1 The Employee and Department Sample Scenario . . . . . . . . . . . . . . . 414.2 The Library Sample Scenario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

Part 2. Your First Samples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

Chapter 5. Employee Top-Down . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475.1 Define the Model (Metadata) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

5.1.1 Create New Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475.1.2 Define Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495.1.3 Define Attributes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505.1.4 Define Relationships. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

5.2 Generate Code for the Model Classes . . . . . . . . . . . . . . . . . . . . . . . . 545.2.1 Set Model Code Generation Options . . . . . . . . . . . . . . . . . . . . . 545.2.2 Start Model Code Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

5.3 Generate Schema and Mapping (Metadata and Database) . . . . . . . . 575.3.1 Generate Image Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 575.3.2 Verify Local Image Schema and Data Store with Scripts. . . . . . . 585.3.3 Version, Release, and Save the Sample Work . . . . . . . . . . . . . . 605.3.4 Generate Database Schema. . . . . . . . . . . . . . . . . . . . . . . . . . . . 615.3.5 Generate the DDL and the Database Tables . . . . . . . . . . . . . . . 66

5.4 Generate Service Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 695.4.1 Set the Service Code Generation Options . . . . . . . . . . . . . . . . . 695.4.2 Start Service Code Generation . . . . . . . . . . . . . . . . . . . . . . . . . . 70

5.5 Activate a Data Store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 715.6 Run Sample Headless with Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

5.6.1 Run Scripts Stepwise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 735.6.2 Monitor Headless Sample with Status Browser . . . . . . . . . . . . . . 75

iv Using VisualAge Smalltalk ObjectExtender

5.7 Do Some Smalltalk Inspection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 765.7.1 Use the Basic Smalltalk Inspector (#inspect) . . . . . . . . . . . . . . . 765.7.2 Use the ObjectExtender Enablement for the Inspectors . . . . . . . 785.7.3 Look at All Instances of a Class (#allInstances) . . . . . . . . . . . . . 79

5.8 Create Views with Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 835.8.1 Use the Basic Transaction Parts. . . . . . . . . . . . . . . . . . . . . . . . . 835.8.2 Use the BusinessTransaction Part . . . . . . . . . . . . . . . . . . . . . . . 90

5.9 Run Sample with User Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 965.9.1 Add Error Handling and Error Events . . . . . . . . . . . . . . . . . . . . . 975.9.2 Add Error Information for the User . . . . . . . . . . . . . . . . . . . . . . . 995.9.3 Add Database Error Handling . . . . . . . . . . . . . . . . . . . . . . . . . . 100

Page 7: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

5.10 Stand-alone Application (GUI with Image Schema) . . . . . . . . . . . . 1015.11 Summary and Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

Chapter 6. Employee Bottom-Up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1056.1 Import Schema from Relational Database (Metadata) . . . . . . . . . . . 1066.2 Generate Model Definition and Mapping (Metadata) . . . . . . . . . . . . . 1096.3 Generate Code to Support Model and Services . . . . . . . . . . . . . . . . 1116.4 Run Sample Headless with Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . 1136.5 Adding the User Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115

6.5.1 Create a List View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1166.5.2 Create a Detail View. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

6.6 Run and Monitor the List and Detail View GUI . . . . . . . . . . . . . . . . . 122

Chapter 7. Employee and Department Top-Down . . . . . . . . . . . . . . . . 1277.1 Define Model (Metadata) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127

7.1.1 Create New Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1287.1.2 Define Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1287.1.3 Define Attributes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1287.1.4 Define Associations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129

7.2 Generate Code for the Model Classes . . . . . . . . . . . . . . . . . . . . . . . 1357.2.1 Generate Model Code into Different Applications . . . . . . . . . . . 1357.2.2 Review Generated Model Class Code . . . . . . . . . . . . . . . . . . . 136

7.3 Generate Schema and Mapping: Metadata and Database . . . . . . . . 1387.3.1 Review the Schema and the Mapping. . . . . . . . . . . . . . . . . . . . 1397.3.2 Generate Conforming Physical Names . . . . . . . . . . . . . . . . . . . 1407.3.3 Match with the DB2 Sample Database (Optional) . . . . . . . . . . . 1437.3.4 Change the Column Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1437.3.5 Change the Key Column Types . . . . . . . . . . . . . . . . . . . . . . . . 144

7.4 Generate Physical Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1457.5 Generate Service Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1467.6 Run Sample Headless with Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . 146

7.6.1 Set up Sample Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1487.6.2 Navigate the Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154

v

7.7 Run Sample with User Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1617.7.1 Single Window GUI for Employee Creation and Maintenance . . 1617.7.2 Convenience Attributes and Methods . . . . . . . . . . . . . . . . . . . . 1647.7.3 GUI with List and Detail Views Supporting Drag and Drop . . . . 1707.7.4 Transaction Save GUIs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190

Chapter 8. Employee and Department Bottom-Up . . . . . . . . . . . . . . . 1958.1 Import Schema from Relational Database (Metadata) . . . . . . . . . . . 196

8.1.1 Select Tables and Import Schema . . . . . . . . . . . . . . . . . . . . . . 1968.1.2 Review and Adjust Imported Schema . . . . . . . . . . . . . . . . . . . . 197

8.2 Generate Model Definition and Mapping (Metadata) . . . . . . . . . . . . . 201

Page 8: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

8.2.1 Review and Adjust the Generated Model Definitions. . . . . . . . . 2038.2.2 Review and Adjust the Generated Mappings . . . . . . . . . . . . . . 205

8.3 Generate Model Code Classes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2098.4 Generate Service Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2108.5 Run Sample Headless with Scripts . . . . . . . . . . . . . . . . . . . . . . . . . . 211

8.5.1 Accessing the Data in the Database . . . . . . . . . . . . . . . . . . . . . 2118.5.2 Navigating the Object Links . . . . . . . . . . . . . . . . . . . . . . . . . . . 211

8.6 Run Sample with User Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214

Chapter 9. Employee and Department - Outside-In . . . . . . . . . . . . . . 2279.1 Preparation Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2279.2 Create the Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2279.3 Create Table Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2289.4 Map Attributes to Columns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2299.5 Map Associations to Foreign Key Relationships . . . . . . . . . . . . . . . . 2309.6 Generate the Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2319.7 Run the Sample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232

Chapter 10. Summary and Conclusion . . . . . . . . . . . . . . . . . . . . . . . . 237

Part 3. Advanced Details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239

Chapter 11. Many-to-Many Associations . . . . . . . . . . . . . . . . . . . . . . 24111.1 Define the Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24111.2 Define Schema and Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24411.3 Test Sample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246

11.3.1 Run Sample Headless with Scripts . . . . . . . . . . . . . . . . . . . . . 24611.3.2 Hiding Implementation Details . . . . . . . . . . . . . . . . . . . . . . . . 24611.3.3 Run Sample with User Interface . . . . . . . . . . . . . . . . . . . . . . . 251

Chapter 12. Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25712.1 Single Table Inheritance Mapping . . . . . . . . . . . . . . . . . . . . . . . . . 258

12.1.1 Define the Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259

vi Using VisualAge Smalltalk ObjectExtender

12.1.2 Define the Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26012.1.3 Define the Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26212.1.4 Test Single Table Inheritance Mapping Sample . . . . . . . . . . . 264

12.2 Multiple Table Inheritance Mapping . . . . . . . . . . . . . . . . . . . . . . . . 26912.2.1 Define the Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27012.2.2 Define the Schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27012.2.3 Define the Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27212.2.4 Test Multiple Table Inheritance Mapping Sample . . . . . . . . . . 273

Page 9: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 13. Selective Queries or Custom Queries . . . . . . . . . . . . . . . 27713.1 Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27713.2 Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27813.3 Add a New SQL Query String to the QueryPool . . . . . . . . . . . . . . . 27913.4 Add a New Method to the Home Collection Class . . . . . . . . . . . . . . 27913.5 Add a Service to the Service Object . . . . . . . . . . . . . . . . . . . . . . . . 28013.6 Run Sample Headless with a Script . . . . . . . . . . . . . . . . . . . . . . . . 282

Chapter 14. Nested Transactions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28314.1 Scenario for the Transaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28314.2 The Nested Transaction Problem . . . . . . . . . . . . . . . . . . . . . . . . . . 28414.3 How Not to Create the Transaction Tree . . . . . . . . . . . . . . . . . . . . 28514.4 A Better Way to Create the Transaction Tree . . . . . . . . . . . . . . . . . 28614.5 The Easy Way to Create a Transaction Tree . . . . . . . . . . . . . . . . . 29614.6 Define Model (Metadata) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29814.7 Generate Schema (Metadata) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30014.8 Generate Mappings (Metadata) . . . . . . . . . . . . . . . . . . . . . . . . . . . 30314.9 Generate Service Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30414.10 Hiding the Auxiliary CategoryLink Class . . . . . . . . . . . . . . . . . . . . 305

14.10.1 Deletion of a Subcategory and Its Associated Link Object . . 30514.10.2 Finding the Subcategories Directly . . . . . . . . . . . . . . . . . . . . 30614.10.3 Setting and Getting the Parent Category Directly . . . . . . . . . 30614.10.4 Adding and Removing a Subcategory Directly . . . . . . . . . . . 307

14.11 Add Some Convenience to the Category . . . . . . . . . . . . . . . . . . . 30814.11.1 Reference String Methods . . . . . . . . . . . . . . . . . . . . . . . . . . 30814.11.2 All Instances Sorted . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309

14.12 Run Samples Headless with Scripts . . . . . . . . . . . . . . . . . . . . . . . 30914.13 The Category Management System Application . . . . . . . . . . . . . . 310

14.13.1 Category List View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31014.13.2 Category Detail View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317

Chapter 15. Concurrent Transactions . . . . . . . . . . . . . . . . . . . . . . . . . 32515.1 Isolation Policies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325

vii

15.2 Optimistic Locking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32615.2.1 Collision Detection in the Image . . . . . . . . . . . . . . . . . . . . . . . 32615.2.2 Collision Detection on the Back-End Data Store . . . . . . . . . . . 332

15.3 Pessimistic Locking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33515.4 Summary of Transaction Characteristics . . . . . . . . . . . . . . . . . . . . 336

Chapter 16. Binary Large Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33716.1 Create a New Part Named GifImage . . . . . . . . . . . . . . . . . . . . . . . 33716.2 Define the Part’s Public Interface . . . . . . . . . . . . . . . . . . . . . . . . . . 33716.3 Provide the Part’s Implementation . . . . . . . . . . . . . . . . . . . . . . . . . 338

Page 10: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 17. Lite Collections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34117.1 Define Model, Schema, and Mapping . . . . . . . . . . . . . . . . . . . . . . . 34117.2 Create a View with a Lite Collection . . . . . . . . . . . . . . . . . . . . . . . . 34217.3 Create a View with a BLOB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345

Appendixes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349

Appendix A. Overview of the Examples in This Book . . . . . . . . . . . . . 351

Appendix B. Naming Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353

Appendix C. Downloadables, ConfigMaps, Applications . . . . . . . . . . 355

Appendix D. Workspaces and System Transcript Output . . . . . . . . . . 361D.1 Rb20HDL.wsp - Headless Test Workspace . . . . . . . . . . . . . . . . . . . . . . 361D.2 Rb30DBCR.txt - DB Table Creation Report . . . . . . . . . . . . . . . . . . . . . . 365D.3 Rb30ObjW.wsp - System Transcript (Output Only) . . . . . . . . . . . . . . . . 366

Appendix E. Library Management System . . . . . . . . . . . . . . . . . . . . . . . 377

Appendix F. Some Survival Stuff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389F.1 VapModelBrowserControl>>#deleteAssociation. . . . . . . . . . . . . . . . . . . 389F.2 VapSchemaColumnEditorModel>> #areForeignKeysValid . . . . . . . . . . 389F.3 Required Self-Associations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391F.4 Non-Required, One-to-Xxx Association . . . . . . . . . . . . . . . . . . . . . . . . . 392

F.4.1 Forward: Nil-Ability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393F.4.2 Backward: Individual Access Solution (Overriding) . . . . . . . . . . . . 394F.4.3 Backward: Generic Access Solution (New Inheritance) . . . . . . . . . 396

F.5 SQL Execution Order in Multiple Table Inheritance Mapping . . . . . . . . . 398F.6 Transaction>>#hasModifications Support. . . . . . . . . . . . . . . . . . . . . . . . 400F.7 Transaction Name Form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405F.8 List Connections Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405

viii Using VisualAge Smalltalk ObjectExtender

Appendix G. Special Notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407

Appendix H. Related Publications. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409H.1 International Technical Support Organization Publications . . . . . . . . . . 409H.2 Redbooks on CD-ROMs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409

How to Get ITSO Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411How IBM Employees Can Get ITSO Redbooks . . . . . . . . . . . . . . . . . . . . . . . 411How Customers Can Get ITSO Redbooks. . . . . . . . . . . . . . . . . . . . . . . . . . . 412IBM Redbook Order Form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413

Page 11: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415

List of Abbreviations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419

ITSO Redbook Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443

ix

Page 12: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

x Using VisualAge Smalltalk ObjectExtender

Page 13: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figures

1. Class Diagram for the Employee and Department Model. . . . . . . . . . . . . . . . . . . . . 32. Class Diagram with All Associations and Roles Annotation . . . . . . . . . . . . . . . . . . . 43. Application Layers and Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54. Components of the Persistence Layers at Development and at Runtime . . . . . . . . 65. Association Editor: Department-Employees Association . . . . . . . . . . . . . . . . . . . . . 86. Foreign Key Relationship Editor with workDepartment Foreign Key . . . . . . . . . . . . 97. Property Map Editor with Class Attribute and Table Column Mapping . . . . . . . . . . 108. Property Map Editor with departmentToEmployee Association . . . . . . . . . . . . . . . 109. A Nested Transaction Tree. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1210. VisualAge Smalltalk ObjectExtender: Frameworks. . . . . . . . . . . . . . . . . . . . . . . . . 1411. Development Paths in a Relational Database Environment . . . . . . . . . . . . . . . . . . 2112. VisualAge Smalltalk ObjectExtender Tools Menu. . . . . . . . . . . . . . . . . . . . . . . . . . 2313. Model Browser: Model Rb01Employee. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2414. Class Editor: Class Employee. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2515. Attribute Editor: Attribute employeeNumber . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2516. Association Editor: Association Department-Employees . . . . . . . . . . . . . . . . . . . . 2617. Schema Browser: Schema Rb01Employee01 (Part 1 of 2) . . . . . . . . . . . . . . . . . . 2718. Schema Browser: Schema Rb01Employee01 (Part 2 of 2) . . . . . . . . . . . . . . . . . . 2819. Table Editor: Employee Table. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2920. Column Editor: empno Column. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3021. Foreign Key Relationship Editor: workDepartment . . . . . . . . . . . . . . . . . . . . . . . . . 3122. Map Browser: Map Rb01Employee (Part 1 of 2) . . . . . . . . . . . . . . . . . . . . . . . . . . 3223. Map Browser: Map Rb01Employee (Part 2 of 2) . . . . . . . . . . . . . . . . . . . . . . . . . . 3324. Property Map Editor: Attributes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3425. Map Property Editor: Associations (Relations) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3426. Status Browser: View Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3527. System Transcript with Log and ObjectExtender Tools Menu . . . . . . . . . . . . . . . . 3628. Smalltalk Class Editor Comment Showing the Textual Summary . . . . . . . . . . . . . 3729. VisualAge Script Editor Comment Showing the Textual Summary. . . . . . . . . . . . . 3830. ObjectExtender Tools Menu: Enable Inspectors Choice . . . . . . . . . . . . . . . . . . . . 40

© Copyright IBM Corp. 1999 xi

31. Library Management System: Overview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4332. Library Management System: Loan Management Use Cases . . . . . . . . . . . . . . . . 4333. Library Management System: Class Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4434. Class Diagram Focusing on the Employee Class. . . . . . . . . . . . . . . . . . . . . . . . . . 4735. Model Browser: Models Menu - New Model and Save Model . . . . . . . . . . . . . . . . 4836. Model Browser: Textual Summary of New (Empty) Rb20Employee Model.. . . . . . 4837. Storage Application and Class for Rb20EmployeeModel . . . . . . . . . . . . . . . . . . . . 4938. Model Browser: Classes Menu - New, Edit, and Delete Class . . . . . . . . . . . . . . . . 4939. Class Editor: New Rb20Employee Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5040. Model Browser: Rb20Employee Model with (Empty) Employee Class. . . . . . . . . . 50

Page 14: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

41. Model Browser: Attributes Menu - New, Edit, and Delete Attribute . . . . . . . . . . . . 5242. Attribute Editor: Attribute Named birthDate of Type Date . . . . . . . . . . . . . . . . . . . . 5243. Model Browser: Rb20Employee Class with Attributes . . . . . . . . . . . . . . . . . . . . . . 5344. Class Editor: Making empNo the Object ID of Class Rb20Employee. . . . . . . . . . . 5345. Model Code Generation Options and Class Selection Dialogs. . . . . . . . . . . . . . . . 5446. Code Application and Classes for Rb20EmployeeModel . . . . . . . . . . . . . . . . . . . . 5647. Class Selection Dialog when Starting the Generation . . . . . . . . . . . . . . . . . . . . . . 5748. Image Schema Application and Service Classes . . . . . . . . . . . . . . . . . . . . . . . . . . 5849. Generated Schema Rb20Employee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6250. Table Editor: Rb20Employee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6351. Column Editor: Column empNo of Rb20Employee Table. . . . . . . . . . . . . . . . . . . . 6452. Map Browser: Rb20Employee Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6553. DDL to Create the Rb20Employee Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6654. Database Connection Dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6755. System Transcript Showing Results of Creating the Database . . . . . . . . . . . . . . . 6856. Service Code Generation Options for DB2 Database. . . . . . . . . . . . . . . . . . . . . . . 6957. Services Generated for Rb20Employee and DB2 . . . . . . . . . . . . . . . . . . . . . . . . . 7058. Conceptual View of Activating a Data Store . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7159. DataStore>>#activate Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7260. Debugger Stopped on “self halt.” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7361. Result of Making a Single Employee Object Persistent . . . . . . . . . . . . . . . . . . . . . 7462. First Inspection of the Attributes through the Instance Variables . . . . . . . . . . . . . . 7763. Inspecting an Attribute through the Getter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7764. Second Inspection of the attributes through the Instance Variables. . . . . . . . . . . . 7865. Enabled Inspector Showing the Values of the Instance Variables . . . . . . . . . . . . . 7966. Initial Result of Rb20Employee allInstances: No Instances . . . . . . . . . . . . . . . . . . 8067. Result after One Read and an Attribute Access . . . . . . . . . . . . . . . . . . . . . . . . . . . 8168. Two Instances After an Update to an Attribute. . . . . . . . . . . . . . . . . . . . . . . . . . . . 8169. Object with Original Attribute Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8270. Object with Changed Attribute Values. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8271. Employee View1 Using the sharedTransaction and topLevelTransaction . . . . . . . 8472. Parts List of the Rb20EmployeeView 1, 2 and 4, and 3 . . . . . . . . . . . . . . . . . . . . . 85

xii Using VisualAge Smalltalk ObjectExtender

73. View with the sharedTransaction and topLevelTransaction Parts . . . . . . . . . . . . . 9074. View with the businessTransaction Part . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9075. Transaction Framework Connections of Rb20 EmployeeView 1 through 4 . . . . . . 9276. Public Interface Editor with the validationError Event . . . . . . . . . . . . . . . . . . . . . . . 9777. errorPrompter Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9978. Validation Error Dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9979. SQL Error Passed by the topLevelTransaction. . . . . . . . . . . . . . . . . . . . . . . . . . . 10080. Local Image Data Store Dedicated Rb20EmployeeView . . . . . . . . . . . . . . . . . . . 10181. DB2 Sample Database: Employee Table with Columns. . . . . . . . . . . . . . . . . . . . 10582. Schema Browser: Import / Export Menu. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10683. Select Tables Dialog: All Tables of the DB2 Sample Database . . . . . . . . . . . . . . 107

Page 15: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

84. Imported Database Schema Rb21Employee . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10785. Imported Table: Still Logical Employee and without Primary Key. . . . . . . . . . . . . 10886. Error message for undefined Primary Key Columns after Import . . . . . . . . . . . . . 10987. Generated Model Rb21Employee. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11088. Generated Map Rb21EmployeeRb21employee . . . . . . . . . . . . . . . . . . . . . . . . . . 11189. Model Generation Options for the Rb21Employee Model . . . . . . . . . . . . . . . . . . 11290. Service Code Generation Options for the Rb21Employee Model. . . . . . . . . . . . . 11291. Database Connection Information for the Rb21Employee Model. . . . . . . . . . . . . 11392. Result of Inspecting Rb21employeeHome singleton allInstances . . . . . . . . . . . . 11493. Extended Trace of Rb21employeeHome allInstances . . . . . . . . . . . . . . . . . . . . . 11494. List Window with Multiple Single Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11595. Rb21EmployeeListView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11696. Rb21EmployeeDetailView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11997. List and Detail View with the Deletion Confirmer in Action . . . . . . . . . . . . . . . . . . 12298. One Plus Four Object Versions of Employee 000030. . . . . . . . . . . . . . . . . . . . . . 12399. View and Inspect Transactions and Transaction Statistics. . . . . . . . . . . . . . . . . . 124100.Fife (1+4) Instances of Employee 000030 in allInstances . . . . . . . . . . . . . . . . . . 125101.Class Diagram for Employee and Department Sample . . . . . . . . . . . . . . . . . . . . 127102.Association Editor View Opens with Name Templates . . . . . . . . . . . . . . . . . . . . 130103.has Association Naming Relationships . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130104.WorksIn Association Naming Relationships. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132105.One-to-One Association: Manages or isManagedBy . . . . . . . . . . . . . . . . . . . . . . 133106.Administers Association . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134107.Model Browser: Department Class. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134108.Rb30 Sample Code Generation Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135109.Model Classes for the Employee and Department Sample . . . . . . . . . . . . . . . . . 137110.Rb30Department Class with Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138111.Generated Schema for Rb30EmployeeTable . . . . . . . . . . . . . . . . . . . . . . . . . . . 139112.Generated Schema for Rb30Department Table. . . . . . . . . . . . . . . . . . . . . . . . . . 140113.Table Column Editor and Foreign Key Relationship Editor . . . . . . . . . . . . . . . . . 141114.Extended Physical Naming Support. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142115.Inconsistent Foreign Key Relationships . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145

xiii

116.Data Sample for Navigation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147117.Inspecting the TOP Department in the Debugger . . . . . . . . . . . . . . . . . . . . . . . . 154118.Access Methods Implemented by Rb30DepartmentHome . . . . . . . . . . . . . . . . . 155119.Usual Access Methods of Rb30DepartmentHome. . . . . . . . . . . . . . . . . . . . . . . . 155120.Access Methods of Rb30Department. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156121.Version V0.2... Enabled Inspector on the S1B Department . . . . . . . . . . . . . . . . . 160122.Version V0.1... Enabled Inspector on the S1B Department . . . . . . . . . . . . . . . . . 161123.Single Window View: Rb30EmployeeView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162124.The Read-Only referenceString Attribute in the Public Interface Editor . . . . . . . . 165125.Rb30DeaprtmentListView. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170126.Rb30EmployeeListView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

Page 16: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

127.Rb99SingleReferenceForm with Drag and Drop Support . . . . . . . . . . . . . . . . . . 172128.Rb99SingleReferenceForm Parts List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173129.Rb30DepartmentDetailView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176130.Rb30DepartmentDetailView Parts List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177131.Rb30EmployeeDetailView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180132.Rb30EmployeeDetailView Parts List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181133.Rb30Department List and Detail View with Data . . . . . . . . . . . . . . . . . . . . . . . . . 189134.Rb30Employee List and Detail Views with Data . . . . . . . . . . . . . . . . . . . . . . . . . 189135.Department Detail Views after a Drag and Drop of an Employee . . . . . . . . . . . . 191136.Map Browser: Defining a Part of the Optimistic Predicate . . . . . . . . . . . . . . . . . . 192137.DB2 Sample Database: Employee Table with Columns . . . . . . . . . . . . . . . . . . . 195138.Select Tables Dialog: Select Department and Employee Table. . . . . . . . . . . . . . 196139.Imported Database Schema Rb31EmpDept . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197140.Foreign Key Relationship Editor: employee_workDepartment. . . . . . . . . . . . . . . 198141.Foreign Key Relationships from Rb30EmpDept Schema . . . . . . . . . . . . . . . . . . 199142.Foreign Key Relationships of the Rb31EmpDept Schema. . . . . . . . . . . . . . . . . . 200143.Generated Rb1employee Model Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201144.Generated Rb31Employee Table Map. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202145.Generated Rb1department Model Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202146.Generated Rb31Department Table Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203147.administrativeDepartment_departments Association . . . . . . . . . . . . . . . . . . . . . . 204148.manager_managedDepartment Association . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204149.workDepartment_employees Association . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205150.Employee VapValidationErrors <<broken: a VapRelationshipMap >>. . . . . . . . . 206151.Department VapValidationErrors <<broken: a VapRelationshipMap >> . . . . . . . 206152.Property Map Editor for Department (see Note below) . . . . . . . . . . . . . . . . . . . . 207153.Property Map Editor Open for Employee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208154.Adjusted Rb31Department Table Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209155.Model Code Generation Options for Rb31EmpDept Model . . . . . . . . . . . . . . . . . 210156.Employees of Department A00 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212157.Department D11 of Employee 000170 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212158.Manager (Employee) 000010 of Department A00 . . . . . . . . . . . . . . . . . . . . . . . . 213

xiv Using VisualAge Smalltalk ObjectExtender

159.Managed Department of Employee (Manager) 000010 . . . . . . . . . . . . . . . . . . . . 213160.Rb31DeptView to Manage Departments in the Composition Editor. . . . . . . . . . . 215161.Rb31DeptView at Runtime to Manage Departments at Runtime . . . . . . . . . . . . . 217162.Rb31DeptView Parts List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223163.New Datastore Map Dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228164.Table Map Creation Dialog. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229165.Property Map Editor with Map Types and Table Columns . . . . . . . . . . . . . . . . . . 230166.Metadata Validation Error: Column Overlap. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230167.Associations Property Map Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231168.Rb30EmpDeptRb31EmpDeptTreeView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232169.Library Management System: Title and Category Analysis View. . . . . . . . . . . . . 241

Page 17: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

170.Library Management System: Title and Category Design View . . . . . . . . . . . . . . 241171.Association between Title and TitleToCategory . . . . . . . . . . . . . . . . . . . . . . . . . . 243172.Association between TitleToCategory and Category . . . . . . . . . . . . . . . . . . . . . . 243173.Rb50TitleToCategory Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244174.Rb50 Title2Category to Rb50Category Foreign Key Relationship . . . . . . . . . . . . 245175.Rb50TitleView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251176.Rb50TitleDetailsView in Composition Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254177.Library Management System: Book and Its Status . . . . . . . . . . . . . . . . . . . . . . . 257178.Example of Three Books and Their Status Mapped into a Single Table . . . . . . . 258179.Settings for the One-to-One Association between Book and Status . . . . . . . . . . 259180.Definition of Borrowed As Subclass of Status . . . . . . . . . . . . . . . . . . . . . . . . . . . 260181.Schema for the Book-Status Example after Automatic Generation . . . . . . . . . . . 261182.Table Map for Class Status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262183.Table Map for Class Available . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263184.allInstances of the Superclass and Subclass Homes. . . . . . . . . . . . . . . . . . . . . . 266185.Example of Three Books and Their Status Mapped to Multiple Tables . . . . . . . . 269186.Definition of the Foreign Key Relationship between Available and Status. . . . . . 271187.Definition of the Status Table Map (Root Inheritance Table Map) . . . . . . . . . . . . 272188.Definition of the Available Table Map (Leaf Inheritance Table Map) . . . . . . . . . . 273189.Typical Transaction Construct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284190.Nested Transaction Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285191.Possible Construct for Recreating the Transaction Tree . . . . . . . . . . . . . . . . . . . 287192.View Tree with Nested Transactions at Runtime . . . . . . . . . . . . . . . . . . . . . . . . . 290193.Select Transaction to Inspect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291194.Inspection of the Top-Level Transaction and Transaction Tree . . . . . . . . . . . . . . 292195.Rb80TransactionExample2View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292196.Typical businessTransaction Construct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297197.Class Diagram of Title-Book-Category Management System Model . . . . . . . . . . 298198.ER Diagram and Schema of the Title-Book-Category Management System. . . . 301199.Rb80CategoryList1View. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311200.Rb80CategoryList2View and Rb80CategoryList3View Extracts . . . . . . . . . . . . . 312201.Rb80CategoryDetailView in Composition Editor . . . . . . . . . . . . . . . . . . . . . . . . . 317

xv

202.Rb80DetailView at Runtime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318203.featureNames of signaller in Rb80DetailView . . . . . . . . . . . . . . . . . . . . . . . . . . . 319204.Rb90TitleView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327205.Rb90TitleDetailsView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330206.Collision Detection in Sibling Nested Transactions . . . . . . . . . . . . . . . . . . . . . . . 332207.Definition of a Lite Collection for Rb11Employee . . . . . . . . . . . . . . . . . . . . . . . . . 342208.Rb11EmployeeView Part . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343209.Rb11EmployeeDetailsView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347210.Library Management System: Use Case List and Sample Use Case . . . . . . . . . 381211.Library Management System: Overview Diagram . . . . . . . . . . . . . . . . . . . . . . . . 385212.Library Management System: Book Management Use Case Diagram . . . . . . . . 385

Page 18: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

213.Library Management System: Customer Management Use Case Diagram . . . . 386214.Library Management System: Book Loan Management Use Case Diagram. . . . 386215.Library Management System: Class Diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . 387216.Zap to Enable Deletion of Unfinished Class Associations . . . . . . . . . . . . . . . . . . 389217.Error When Trying to Change a Key Column Type . . . . . . . . . . . . . . . . . . . . . . . 390218.Zap to Enable Direct Foreign Key Relationship Column Type Change . . . . . . . . 390219.Key Column Type Definition Inconsistency Warning . . . . . . . . . . . . . . . . . . . . . . 391220.Inconsistent Foreign Key Relationships . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391221.Zap for Required Self Referencing Associations (Stack OVerflow) . . . . . . . . . . . 392222.Zap of Non-Required One-to-One Associations Model Code Generator . . . . . . . 393223.Zap of Generated Non-Required One-to-One Associations Model Code . . . . . . 394224.Dubugger: Non Managing Rb30Employee>>#managedDepartment. . . . . . . . . . 394225.Overriding #objectForForeignKey: Method Just Before Saving It . . . . . . . . . . . . 395226.Class for Method Visibility and Source, and Class for the Method Save . . . . . . . 396227.New Part Dialog for the Rb99EnhancedRelationship Class. . . . . . . . . . . . . . . . . 397228.Rb99EnhancedRelationship>>#objectForForeignKey: Method . . . . . . . . . . . . . . 397229.Prerequisites for Rb99EmpDeptApp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398230.SQL Sequence for Multiple Table Inheritance Mapping. . . . . . . . . . . . . . . . . . . . 400231.Sequence of a Modification Notification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401232.Public Interface: hasModifications Attribute of Transaction . . . . . . . . . . . . . . . . . 404233.Form with Script to Display the Transaction Name . . . . . . . . . . . . . . . . . . . . . . . 405234.DfksListConnectionsView in Composition Editor . . . . . . . . . . . . . . . . . . . . . . . . . 406235.DfksListConnectionsView at Runtime Listing Its Own Connections. . . . . . . . . . . 406

xvi Using VisualAge Smalltalk ObjectExtender

Page 19: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Tables

1. Map Property Type Prefixes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332. Model-Related Names for the Rb20Employee Sample . . . . . . . . . . . . . . . . . . . . . . . . 483. Attributes of the Rb20Employee Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 514. Class Hierarchy of Persistent Objects in ObjectExtender . . . . . . . . . . . . . . . . . . . . . . 555. Class Hierarchy of Persistent Objects in ObjectExtender . . . . . . . . . . . . . . . . . . . . . . 566. Columns for the Rb20Employee Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 637. Connections of Rb20EmployeeView1 (Part 1 of 2) . . . . . . . . . . . . . . . . . . . . . . . . . . . 888. Connections of Rb20EmployeeView1 (Part 2 of 2) . . . . . . . . . . . . . . . . . . . . . . . . . . . 899. Connections Unique to Rb20EmployeeView2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9310. Connections Unique to Rb20EmployeeView3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9311. Connections Unique to Rb20EmployeeView4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9412. Connections of Rb21EmployeeListView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11813. Connections of Rb21EmployeeDetailView. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12114. Attributes for the Rb30Employee Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12815. Attributes for the Rb30Department Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12916. VapDatabasePhysicalRules Class: Major Extending Methods . . . . . . . . . . . . . . . . . 14217. Columns for the Rb30Employee Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14418. Columns for the Rb30Department Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14419. Connections of Rb30EmployeeView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16320. Reference String and fullName Methods of Employee . . . . . . . . . . . . . . . . . . . . . . . 16621. Employee Modifications to Signal Changes of Derived Attributes . . . . . . . . . . . . . . . 16722. Department referenceString Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16823. Department Modifications to Signal Changes of Derived Attributes . . . . . . . . . . . . . 16924. UndefinedObject Extension referenceString . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16925. Connections of Rb99SingleReferenceForm. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17426. Drag and Drop Support Events and Scripts in Rb99SingleReferencesForm. . . . . . . 17427. Promoted Features in Rb99SingleReferenceForm . . . . . . . . . . . . . . . . . . . . . . . . . . 17528. Rb30Department Methods for the Drag-Drop Support . . . . . . . . . . . . . . . . . . . . . . . 17929. Connections of the Rb30DepartmentDetailView (Part 1 of 4) . . . . . . . . . . . . . . . . . . 18230. Connections of the Rb30DepartmentDetailView (Part 2 of 4) . . . . . . . . . . . . . . . . . . 183

© Copyright IBM Corp. 1999 xvii

31. Connections of the Rb30DepartmentDetailView (Part 3 of 4) . . . . . . . . . . . . . . . . . . 18432. Connections of the Rb30DepartmentDetailView (Part 4 of 4) . . . . . . . . . . . . . . . . . . 18533. Connections of the Rb30EmployeeDetailView (Part 1 of 3). . . . . . . . . . . . . . . . . . . . 18634. Connections of the Rb30EmployeeDetailView (Part 2 of 3). . . . . . . . . . . . . . . . . . . . 18735. Connections of the Rb30EmployeeDetailView (Part 3 of 3). . . . . . . . . . . . . . . . . . . . 18836. Foreign Key Relationships for Rb31EmpDept Schema . . . . . . . . . . . . . . . . . . . . . . . 19937. Reference Attributes in the Rb31department Public Interface . . . . . . . . . . . . . . . . . . 21838. Reference Methods of Rb31department . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21839. Reference Attributes in the Rb31employee Public Interface . . . . . . . . . . . . . . . . . . . 21940. Reference Methods of Rb31employee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219

Page 20: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

41. Signalled Attributes in the Rb31department Public Interface. . . . . . . . . . . . . . . . . . . 22042. Signalled Methods in the Rb31department Class . . . . . . . . . . . . . . . . . . . . . . . . . . . 22043. Add.../Remove... Departments Methods in Rb31department Class . . . . . . . . . . . . . 22144. Add.../Remove... Employees Methods in Rb31department Class . . . . . . . . . . . . . . . 22245. Connections of Rb31DeptView (Part 1 of 3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22446. Connections of Rb31DeptView (Part 2 of 3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22547. Connections of Rb31DeptView (Part 3 of 3) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22648. Map Creation Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22849. Rb30EmpDeptRb31EmpDeptTreeView Scripts (Part 1 of 2). . . . . . . . . . . . . . . . . . . 23350. Rb30EmpDeptRb31EmpDeptTreeView Scripts (Part 2 of 2). . . . . . . . . . . . . . . . . . . 23451. Connections of Rb30EmpDeptRb31EmpDeptTreeView . . . . . . . . . . . . . . . . . . . . . . 23552. Rb50Title and Rb50Category Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24253. Rb50Title, Rb50Category, and Rb50TitleToCategory Tables . . . . . . . . . . . . . . . . . . 24554. Connections of Rb50TitleView. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25355. Connections of Rb50TitleDetailsView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25556. Tables, Columns, and Attributes for Status Superclass. . . . . . . . . . . . . . . . . . . . . . . 27057. Tables, Columns, and Attributes for the Subclasses of Status . . . . . . . . . . . . . . . . . 27158. Connections of a Typical Transaction Construct . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28459. Main Connections of Rb80TransactionExample2View . . . . . . . . . . . . . . . . . . . . . . . 28960. Connections of Rb80TransactionExample2View (Part 1 of 2) . . . . . . . . . . . . . . . . . . 29361. Connection of Rb80TransactionExample2View (Part 2 of 2). . . . . . . . . . . . . . . . . . . 29462. Transaction ID Scripts of Rb80TransactionExample2View . . . . . . . . . . . . . . . . . . . . 29563. Title Scripts of Rb80TransactionExample2View . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29664. Connections of Rb80TransactionExample3View. . . . . . . . . . . . . . . . . . . . . . . . . . . . 29765. Attribute Details for the Title, Category, and Book Classes . . . . . . . . . . . . . . . . . . . . 29966. Association Details for the Title, Category, and Book Classes . . . . . . . . . . . . . . . . . 30067. Application Names for Rb80 Model, Schema, and Mapping . . . . . . . . . . . . . . . . . . . 30068. Schema Definitions for Rb80 Sample Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30269. Foreign Key Definitions for the Rb80 Sample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30370. Mapping Details for the Rb80 Sample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30471. Connections of the Rb80CategoryList1View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31472. Connections of the Rb80CategoryList2View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315

xviii Using VisualAge Smalltalk ObjectExtender

73. Connections of the Rb80CategoryList3View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31674. Connections of the Rb80CategoryDetailView (Part 1 of 4) . . . . . . . . . . . . . . . . . . . . 32075. Connections of the Rb80CategoryDetailView (Part 2 of 4) . . . . . . . . . . . . . . . . . . . . 32176. Connections of the Rb80CategoryDetailView (Part 3 of 4) . . . . . . . . . . . . . . . . . . . . 32277. Connections of the Rb80CategoryDetailView (Part 4 of 4) . . . . . . . . . . . . . . . . . . . . 32378. Connections of Rb90TitleView. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32979. Connections of Rb90TitleDetailsView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33180. Attributes of Class Rb11Employee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34181. Connections of Rb11EmployeeView . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34482. Connections of Rb11EmployeeDetailsView. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34683. Overview of Sample Applications in This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351

Page 21: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

84. Naming Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35385. Downloadable File RBOE.zip and Its Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35686. Application Configuration Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35787. Application Utility Configuration Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35788. Import/Export Rb00ConfigMap with All Application (Part 1 of 3) . . . . . . . . . . . . . . . . 35889. Import/Export Rb00ConfigMap with All Application (Part 2 of 3) . . . . . . . . . . . . . . . . 35990. Import/Export Rb00ConfigMap with All Application (Part 3 of 3) . . . . . . . . . . . . . . . . 36091. Import/Export Rb01ConfigMap with ObjectExtender Modifications) . . . . . . . . . . . . . 36092. Library Management System: Requirements. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37893. Library Management System: Concepts 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37894. Library Management System: Concepts 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37995. Library Management System: Actors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38096. Library Management System: Main Use Cases with Hyper Link Marks . . . . . . . . . . 38297. Library Management System: Extending and Used Use Cases 1 with Link Marks . . 38398. Library Management System: Extending and Used Use Cases 2 with Link Marks . . 38499. New Transaction Methods to Notify Modifications . . . . . . . . . . . . . . . . . . . . . . . . . . . 402100.New and Modified TransactionView Methods to Notify Modifications . . . . . . . . . . . . 402101.Modified Version Method to Notify Modifications. . . . . . . . . . . . . . . . . . . . . . . . . . . . 402102.New and Modified BusinessTransaction Methods to Notify Modifications . . . . . . . . 403103.New and Modified TransactionView Methods to Notify Modifications . . . . . . . . . . . . 404

xix

Page 22: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

xx Using VisualAge Smalltalk ObjectExtender

Page 23: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Preface

VisualAge Smalltalk ObjectExtender is the transaction and persistence framework feature of the IBM VisualAge Smalltalk Enterprise product family. ObjectExtender is the sister component to the Persistence Builder of the VisualAge for Java product.

ObjectExtender enables your object models to persist in relational data stores as well as provides linkages to legacy data systems. Creating the persistence layer is accomplished using the ObjectExtender tool set. The tool set helps you describe the business objects in your model that will persist in a data store. The tools generate the supporting code that services your persistent business as well as data definition language for relational databases to create the tables.

ObjectExtender supports various development paths—from the model top-down to the database, from the database bottom-up to the model, and mapping a model to a database schema—with the options to mix full generation, partial generation, and manual entered definitions for the components along the path.

This redbook is intended for analysts, designers, software developers, application experts, and technical project managers who want to become familiar with ObjectExtender. A basic understanding of object and relational technology is assumed. All developed sample applications and test scripts are available as downloadable sources.

The code for the samples in this book is available as SG245258.zip on:

ftp://www.redbooks.ibm.com/redbooks/SG245258

How the Book Is Organized

© Copyright IBM Corp. 1999 xxi

The book is divided into three parts:

Part 1 contains an introduction to ObjectExtender transaction and persistence framework, describes the concepts and functions of the tool including its look and feel, and provides a general understanding and work path guidelines on how to use the tool to go through the development process. Part 1 also includes the introduction to the problem domains used for the samples in this redbook.

Part 2 contains five samples—your first samples—a step by step, simple to challenging hands-on opportunity for you. After practicing through the samples you have a sound understanding how ObjectExtender can solve the

Page 24: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

persistence and transaction problems in your VisualAge Smalltalk applications.

Part 3 contains advanced details, such as how to use ObjectExtender to handle mass data problems, more complex object models, nested and concurrent transactions, and special data, such as binary large objects.

The appendixes contain overview about the samples, the naming conventions, the downloadables. They also include some workspaces, some sample system transcript output, and some survivals.

The Team That Wrote This Redbook

This redbook was produced by a team of specialists from around the world working at the International Technical Support Organization San Jose Center.

Markus Muetschard is an IT and Object-Oriented Consultant at the IBM International Technical Support Organization, San Jose Center. He writes extensively and teaches IBM classes worldwide on all areas of object-oriented technology, with a focus on the VisualAge (Smalltalk) product family. Before joining the ITSO, Markus worked in the IT Consulting department of IBM Switzerland, consulting and mentoring for object-oriented customer projects.

Marianne Schmid is project leader and developer at Credit Suisse and at the STC of OTI (Software Technology Center of Object Technology International Inc. Ottawa, Canada) in Zurich, Switzerland. She has over 15 years of experience in banking and information technology for banking. Marianne’s areas of expertise include analysis, design, and implementation of object-oriented applications and frameworks with legacy system integration.

Bernd Kaponig is an IT Architect with IBM’s Object Technology Practice in Austria. He has 14 years of experience in the software development field. He

xxii Using VisualAge Smalltalk ObjectExtender

holds a Master of Science degree in Computer Science from Technology University Vienna. His areas of expertise include object-oriented analysis, design and implementation, as well as distributed object architectures.

David Singleton is a Software Engineer in Germany. David has over 30 years of experience in computing, in a variety of fields. David currently works for LogicLine Gmbh, an IBM partner firm near Stuttgart in Germany. His areas of expertise include real time systems, database systems and object orientation. David has had articles published on the application of object oriented techniques in C++. David has a Master of Science degree in Computer Science from Imperial College, London, Great Britain.

Page 25: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Thanks to the following people for their invaluable contributions to this project:

Joe R. Winchester, Dibbe A. Edwards, and Brian Lang of IBM VisualAge Development in the RTP (Research Triangle Park), Raleigh, NC, USA

Elsa Barron, Joan Bow, Mary Comianos, Maggie Cutler, Shirley Hentzell, Jean Gedeon, Pat McCarthy, Ueli Wahli, and Laymond M. Pon of the International Technical Support Organization, San Jose Center.

Comments Welcome

Your comments are important to us!

We want our redbooks to be as helpful as possible. Please send us your comments about this or other redbooks in one of the following ways:

• Fax the evaluation form found in “ITSO Redbook Evaluation” on page 443to the fax number shown on the form.

• Use the electronic evaluation form found on the Redbooks Web sites:

For Internet users http://www.redbooks.ibm.com

For IBM Intranet users http://w3.itso.ibm.com

• Send us a note at the following address:

[email protected]

xxiii

Page 26: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

xxiv Using VisualAge Smalltalk ObjectExtender

Page 27: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Part 1. Introductory Tour

© Copyright IBM Corp. 1999 1

Page 28: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

2 Using VisualAge Smalltalk ObjectExtender

Page 29: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 1. Concepts

This chapter describes the VisualAge Smalltalk ObjectExtender concepts, frameworks, and tool components that you need to know to use the product. In describing concepts and frameworks, it is often necessary to talk in somewhat theoretical terms. To avoid this, we use a sample application, the well-known DB2 Employee sample database. We use this sample in part 1 of the book to illustrate the concepts, tools, and development scenarios. In part 2 we develop same sample applications, using ObjectExtender and the Employee database.

In the Employee database, a company administrator maintains data about employees and departments. Employees have a name, phone number, work department, employee number, and other attributes. Departments have a name, a manager, an administrative department (organizational hierarchy), a department number, and other attributes.

Looking at this sample in an object-oriented way, there are two objects, the Employee and the Department. These objects are linked to one another because it is necessary to know:

• Who works in which department?

• Which departments are administered by other departments?

• Which employee manages a department, and which department is it?

Figure 1 shows a class diagram for this employee-department modeled in Unified Modeling Language (UML) notation.

isAdministeredBy >

1

© Copyright IBM Corp. 1999 3

Figure 1. Class Diagram for the Employee and Department Model

< worksIn

isManagedBy >

Department Employee

* 1

*

0..1 0..1

employeeNumbernamephoneNumberworkDepartment...

departmentNumbernamemanageradminDepartment...

Page 30: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Note that the association names and their direction in the class diagram are somewhat biased: they remind one of the relations and foreign keys in the relational Employee database sample. However, with association names in both directions and the roles annotated, the bias does not matter (Figure 2).

< worksIn

isManagedBy >

isAdministeredBy >

Department Employee

* 1

*

1

0..1 0..1

employeeNumbernamephoneNumberworkDepartment...

departmentNumbernamemanageradminDepartment...

managedDepartment

manager

administrative

departments

workDepartment

employees

has >

< administers

< manages

Department

4 Using VisualAge Smalltalk ObjectExtender

Figure 2. Class Diagram with All Associations and Roles Annotation

Page 31: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

1.1 Application Layers

ObjectExtender separates the task of implementing a system into three application layers (Figure 3):

• Application programming. This layer is primarily concerned with the user interface and with the management of updates as complete and consistent units of work (or transactions).

• Object modeling. This layer is primarily concerned with the definition and implementation of business objects and the relationships among these business objects.

• Data access programming. This layer is primarily concerned with the storage and retrieval of data in the underlying database. Together with the object modeling layer, this layer handles the mapping between business objects and database tables. Often, particularly where a new front end is being implemented for a legacy database, there is no one-to-one mapping between the business objects and the related database tables.

Transactions

ObjectModeling

ApplicationProgramming

BusinessObjects

Dialogs

Concepts 5

Figure 3. Application Layers and Components

Services

DataStore

Data AccessProgramming

Page 32: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

1.2 Persistence Layers

ObjectExtender provides a full set of tools to support the development of the mappings between business objects and the underlying database, so that the business object storage can be made persistent. In the development environment, ObjectExtender provides a set of browser tools that allow you to develop object models and create mappings to the underlying database schema. Figure 4 illustrates the persistence layers, the browsers used to manage the metadata at development time, and the generated classes at runtime.

At the bottom of the runtime environment stack is the services layer. This layer is responsible for establishing the connection with the physical database. We discuss it in more detail in 1.5, “Data Abstractions” on page 15. In the sections that follow we explain how a business object can be mapped to a schema.

Development Environment Runtime EnvironmentBrowsers Models

ObjectMeta

Model

BusinessObjects and

Relationships

Home

Transactionswith

ObjectVersions

Classes and Instances

Model

6 Using VisualAge Smalltalk ObjectExtender

Figure 4. Components of the Persistence Layers at Development and at Runtime

Maps

Data-base

Schema

Collections

Services

Map

Schema

Page 33: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

1.2.1 Business ObjectsThe simple example has only two objects and therefore two classes: Employee and Department.

For the purposes of this discussion, we consider only a subset of the Employee class, with the following significant attributes:

• employeeNumber, for employee number • lastName, for last name or name

Observant readers will notice that one attribute is apparently missing from the simple list of attributes: the attribute that indicates in which department this employee works (workDepartment).This is a deliberate omission because workDepartment is not an attribute of the Employee class. Instead, it is a link (association in UML terms) between the Employee class and the Department class, supporting the worksIn association shown in Figure 2 on page 4.

If you want to try this, use the ObjectExtender Model Browser and it’s tools to create the object model, create the classes called Employee and Department, and add the attributes and associations. In the model, the association worksIn respectively has in Figure 2 on page 4 is now named Department-Employees, because it is a one-to-many association between these two classes, as shown in Figure 5.

Notice that the related roles, workDepartment and employees are preserved and used to describe the same roles of the Department for the Employee and vice versa.

Observant readers will also notice that the association is navigable in both directions. It is possible to find the employees in a particular department from that Department object. Similarly, one can identify the department in which an employee works from the relevant Employee object. You should distinguish between this object-oriented view of the Employee sample and

Concepts 7

the relational view of that same sample. In the relational view, you cannot find out which employees belong to a department by asking the Department table. Instead, you have to query the Employee table as well.

There is also another association between the Department class and the Employee class, namely, isManagedBy, which will now be named Department-Employee, indicating a one-to-one association. If the class names do not adequately specify the roles, or there are multiple associations between two classes and the Classname1-Classname2 naming pattern creates the same or indistinct names for them, consider why the Role1-Role2

Page 34: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

naming pattern or a combination of both. The association names would read: Department-Employees and Department-Manager or WorkDepartment-OccupiedEmployees and ManagedDepartment-ManagingEmployee.

Figure 5. Association Editor: Department-Employees Association

Adding the remaining attributes for the Employee class (for example, birthDate, phoneNumber) is a simple graphical exercise left for Part 2, “Your First Samples” on page 45 of this book.

1.2.2 SchemasA physical database with tables (for a relational database) is required to support the object model. If the application was developed completely from

8 Using VisualAge Smalltalk ObjectExtender

scratch, the ObjectExtender schema generation of the Schema Browser with tools, could be used to create a schema. ObjectExtender creates the necessary data definition language (DDL) for the database or creates the tables, indices, and constraints directly from the schema.

Here, this is not necessary because the DB2 SAMPLE database is supplied with DB2. The ObjectExtender Schema Browser can therefore be used to interrogate DB2 for the tables to reverse-engineer a schema definition for use by ObjectExtender. Because the database does not include the necessary

Page 35: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

constraints, you have to add foreign key definitions. Figure 6 shows the relevant definition for the worksIn relationship.

Figure 6. Foreign Key Relationship Editor with workDepartment Foreign Key

1.2.3 MapsIf a database schema for a new application is generated directly from the object model, ObjectExtender automatically generates the necessary mappings between the business objects and the database tables. As it is,

Concepts 9

existing database tables are available and have been used to generate an ObjectExtender schema from the tables. Mappings must be created between the business objects and the database tables.

ObjectExtender also supplies a Map Browser to help with this task. The Map Browser with tools is used to create mappings between class attributes and table columns, as shown in Figure 7.

Class associations must be mapped to table foreign keys, as illustrated in Figure 8.

Page 36: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 7. Property Map Editor with Class Attribute and Table Column Mapping

10 Using VisualAge Smalltalk ObjectExtender

Figure 8. Property Map Editor with departmentToEmployee Association

The managedDept association is not mapped to a column in the Employee table because the table contains no information that says which (if any), department the employee manages. This information is supplied through the Employee object by the EmployeeToDepartmentRelationship and is derived from the manager column in the Department table.

Page 37: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

1.3 Transactions

As an environment for developing data processing applications, ObjectExtender naturally supports the concept of the transaction. It supports a number of different types of transaction, as described below. With the exception of the global shared transaction, all transactions must be owned by a parent transaction.

The ObjectExtender transaction supports a variety of synchronization and collision or conflict management schemas.

Synchronization between application and data memory spaces is achieved by various synchronization schemes. These schemes define when modified objects in the application memory are sent to the database and when objects are refreshed from the database. For example, a deferred write schema would imply that modified objects are first recorded within a transaction. When the transaction is committed, the modified objects are automatically written to the database all at once.

Collision management schemes provide different approaches according to the different types of transactions defined. Transactions with a high penalty for failure, for example, could have a pessimistic collision prevention scheme, whereas transactions with a low penalty for failure—that is, where it is worth the risk of failure to gain the efficiency—could have an optimistic collision detection scheme. A flexible collision management scheme is based on the properties of the transaction, the domain class, and the data store. For example, within a transaction there may be participating objects that are not ycandidates for collision. When the transaction directs its participants to lock their resources, the objects that are not collision candidates do nothing because they have no resources that require locking. The net effect of collision management strategies depends entirely on what the underlying data store supports.

Concepts 11

1.3.1 Shared TransactionObjectExtender requires that every VisualAge application has a minimum of one transaction active at any one time. To ensure that this is always the case, ObjectExtender implements the global shared transaction. This transaction is created when a VisualAge application is started and remains in existence until the application finishes. The shared transaction has one restriction that other transactions lack: it is read-only.

Page 38: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

If your only aim when developing an application is to browse data (that is, no updates, inserts, or deletes), the shared transaction supplies all the transaction functionality that you need.

The shared transaction also acts as the parent transaction for all top-level transactions.

1.3.2 Top-Level TransactionsTop-level transactions are always child transactions of the global shared transaction. They supply all of the functionality required for simple interactions with the database involving browsing, inserts, updates, and deletes. A number of top-level transactions can be active at any one time.

1.3.3 Nested TransactionsIt is sometimes necessary to divide one overall transaction down into a number of subparts. For example, as shown in Figure 9, a transaction consists of three subtransactions A, B, and C. Subtransaction A consists of two subparts, A1 and A2. This pattern of top-level transactions and multiple level subtransactions is called a nested transaction.

Top-Level Transaction

Subtransaction A Subtransaction CSubtransaction B

Subtransaction A1 Subtransaction A2

12 Using VisualAge Smalltalk ObjectExtender

Figure 9. A Nested Transaction Tree

The transaction has been divided into parts because the design requires that it be possible to roll back individual subtransactions without having to go back to the beginning of the transaction. Dividing of transactions may be driven by user interface considerations. For example, say a user has to enter a lot of information on a number of screens to complete a new customer entry. If that user makes a mistake partway through, it is cumbersome to have to go back to the very beginning to correct the error.

Page 39: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

1.3.4 Transacted VariablesAt any point in time, it is possible to have several transactions in existence. However, only one of these transactions is the current transaction. ObjectExtender provides facilities to allow switching between transactions. For variables holding a transient (non-persistent) object, this does not present a problem. However, for variables holding a persistent object, where changes to the object through the variable can be committed or rolled back, it is important to know which transaction is associated with the object and the variable so that the commitment or rollback can be correctly handled.

It is therefore possible, in advanced scenarios such as running parallel transactions, that the normal association between a variable and a transaction may be lost. ObjectExtender uses the current transaction as the context for changing an object through a variable. If the variable was actually associated with another transaction, the object will be altered in the context of the wrong transaction. Actually the wrong object is changed, because each transaction creates and keeps a version of each object changed in its context—its associated object version.

ObjectExtender provides, through the transacted variable, a mechanism for explicitly ensuring that a transacted variable is associated with a specific transaction, and also access to the object in the transacted variable. Whenever a change is made to an object through such a transacted variable, the change is made only within the context of the associated transaction.

On a rollback of a transaction, each associated object version is discarded. On a commit of a transaction, the changes in each associated object version are merged into the object version, from where it was derived. Therefore, the changes in the committed transaction are merged to the parent transaction. If the object version is the version read from the persistence, and so the associated transaction is the top-level transaction, the objects become the new persistent version and are written to the persistent storage.

Concepts 13

ObjectExtender detects collisions, also called conflicts, while merging changes into higher object versions or transaction levels as well as to persistent storage. A collision occurs, if a second merge to the same level of object version and transaction from a logically lower level is initiated. Merge policies can be defined that ObjectExtender can handle collisions automatically or invoke application-defined code that handles the collision. Unhandled collisions roll back the transaction that tries to commit.

Page 40: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

1.4 Frameworks

ObjectExtender is a framework of frameworks, developed to reduce the amount of code that application developers subsequently need to produce. The ObjectExtender framework consists of the frameworks shown in Figure 10.

Figure 10. VisualAge Smalltalk ObjectExtender: Frameworks

Each of these frameworks addresses a different part of the development task:

• Modeling framework. The modeling framework, supported by the Model Browser, allows you to build up the definition of an object model interactively, specifying the object classes in the model, the attributes of each class, and the associations among the various classes. The framework then provides tools for automatic code generation (and

Transaction Framework

Mapping Framework Data Store Framework

ObjectExtender Framework

Modeling Framework Relationship Framework

14 Using VisualAge Smalltalk ObjectExtender

re-generation after amendment of the model). The generated code provides places for you to insert code for special processing, such as business rule validation, and preserves such code should the automatic code regeneration be invoked again.

• Relationship framework. In any real-world application, the classes in the object model are related to one another. The ObjectExtender relationship framework, supported by all three browsers, allows you to specify the relationships between objects and the foreign key relationships between the tables in the underlying data store. Code generation to allow navigation along the relationship paths is provided.

Page 41: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

• Transaction framework. ObjectExtender provides a set of transaction objects to control access to the underlying data store to ensure that all changes to the data store are applied in a consistent and controlled manner.

• Mapping framework. Once the object model and the underlying data schema are defined, it is necessary to map the one to the other. The mapping framework, supported by the Mapping Browser, enables you to do that.

• Data Store framework. The data store framework, supported by the Schema Browser, allows you to build definitions of the underlying physical data store. If a new data store is being developed, the framework generates the requisite DDL to build the required data store. If a legacy relational data store is available, the framework can interrogate the data store to build the requisite ObjectExtender view of the data store.

1.5 Data Abstractions

ObjectExtender holds information about the application in a number of levels, each representing a different level of abstraction of the overall model design and implementation. It is important that you are aware of these levels and can distinguish among them. We summarize them below:

1.5.1 Model MetadataWe call the data that ObjectExtender needs to store about the design of a particular application metadata, to distinguish it from the application data (such as the data stored in the Employee or Department tables) that the application must process to carry out its normal function.

The metadata is stored as part of the application in the application image. It is not available to the developed application at runtime.

Concepts 15

1.5.2 Application ScriptsObjectExtender uses the model metadata to generate real model application scripts (code). These scripts are also stored as part of the application in the application image. They are executed at runtime to process the application data.

You can extend the generated scripts to add to or change the generated functionality.

Page 42: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

1.5.3 Application DataThe data on which the application operates can be stored in a number of ways, depending on application design considerations. For example, the data can be stored in a (legacy) database, for which no Smalltalk binding exists, or the access has to go through (legacy) non-Smalltalk access modules. In this case, it may be necessary to develop special-purpose code in the services layer to call the database application programming interfaces (APIs) or the access modules directly. ObjectExtender generates the Smalltalk stubs to fill in the special-purpose code as well as their invocation in the framework.

If the database has an open data base connectivity (ODBC) driver, standard ODBC calls are inserted to access the database when the services layer is generated. Similarly, ObjectExtender can automatically generate code to access an IBM DB2 database through the command language interface (CLI).

Finally, it is possible to hold the application data as persistent data within the local image. This is useful for small stand-alone applications and for application development. The same model is used whether the connection is with a database or with the local image, so the application design and code are unaffected. Only the generated services need to be swapped to use either the database or the local image data store. The local image data store service object has a protocol to save the data store to a file, load it from a file, and reset (empty) it—invoked from the status tool or Smalltalk code.

1.6 Metadata and Its Storage

The three main pieces that are defined to support a Object Extender application are the model, the schema, and the data store map. The information for each of these is stored in a class in the development repository. When a model, schema, or map is first created, you can edit without having to save it. In this case all changes are recorded in the image and are only available to you in your image. To save the work and make it

16 Using VisualAge Smalltalk ObjectExtender

available to other users, use the Save option from each of the browsers. This option stores the details of the model, map, or schema in a class in the development repository to which the image is attached. If a model, map, or schema requires saving, the browser indicates this in a text pane on the lower half of the window.

After a model, map, or schema has been saved, it can be loaded by other users into their images by loading the storage class in the same way any other Smalltalk class is loaded from the repository into the image. (To load a class into the image, it must be a version, or if it is still an edition, the user of the image must be the developer of the edition.)

Page 43: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

After loading the classes that hold the metadata information for a model, map, or schema into the image, the browsers are not automatically refreshed. You have to use the Load Available menu option. This option will hydrate the models, maps, or schema in the image from the list of loaded classes that are holding the metadata information. As you work with the model, map, or schema in the browser, the changes are recorded locally in your image. The browser signals that the class is out of step with the image by indicating that it is dirty and requires saving. If you decide not to save the changes you can revert the model, map, or schema to the version last saved to the storage class by using the Revert menu option. To store your work in the development repository, use the Save menu option to take the definitions (which are always the definitions the browsers show) of the model, map, or schema from your image and store them in the repository. From here, you can version the classes and applications, using the VisualAge Organizer or one of the other development repository browsers, and then another user can load and work on them.

It is good practice to version the class containing the metadata for the model, map, or schema before another user loads it into his or her image. Once the storage class has been versioned, it can be moved between development repositories, using the Import and Export menu options. When the class is exported, it takes the metadata with it, allowing ObjectExtender models, maps, and schemas to be moved between repositories.

Concepts 17

Page 44: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

18 Using VisualAge Smalltalk ObjectExtender

Page 45: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 2. Development Paths

The development paths you decide to use depend on whether you develop your application from scratch or use legacy (data access) code or existing (relational) databases. Figure 11 gives an overview of the three typical development paths in a relational database environment:

• Forward or top-down: Start with the model

• Backward or bottom-up: Start with the (legacy) database

• Outside-in: Map the object model to the database schema

2.1 Forward or Top-Down: Start with the Object Model

The forward or top-down path is the typical path for developing an application from scratch (Figure 11 on page 21).

The first step is to define the model by the metamodel. From then on everything else is just a matter of clicking a button: generating the business object classes, the database schema, mapping, and service classes and creating the database. You can control every generation step and make adjustments to the generation options as well as to the results created by ObjectExtender.

For situations beyond average requirements, such as complex models, special inheritance implementations, or tuned database access, the forward or top-down path is still the most appropriate. Even if you have to attach the legacy (data access) code and database, the generated results up to the schema are a good basis for starting with the changes and adjustments.

Currently, the metamodel has to be entered manually in the model definition support of ObjectExtender. Import or capturing support will be available soon: a bridge to VisualAge (Smalltalk) UML Designer, IBM’s object-oriented

© Copyright IBM Corp. 1999 19

modeling and design tool, supports the import of object models and designs into ObjectExtender.

The forward or top-down path is also typical for prove of concept, prototypes, rapid application development (RAD), "check-outs," and initial versions of an applications. The operational and subsequent versions and extensions of the applications will then be developed along the path described in 2.3, “Outside-In: Map the Model to the Database Schema” on page 22. This path guarantees the option for a clean object-oriented implementation of the business model as well as for implementing state-of-the art database implementations.

Page 46: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

For prototyping (and RAD) ObjectExtender offers an even faster option than automatic generation of the schema, map, and database: the image schema and image data store generation feature. With this feature all you have to do to get ready for testing or showing a persistent model at live is define the model. Generating the model classes and the image schema from the model definition is just a matter of clicking a button.

The generation of the image schema from the model definition generates only a data store, no schema, no map, and no service classes. The data store is kept in the image as a local image data store and can be saved as a binary object dump to a file and later reloaded. Therefore, using the image schema generation feature of ObjectExtender does not require a database system to be installed. The feature is also very convenient for rerunning scenarios with prototypes for demonstration purposes. (You could even imagine a stand-alone, single user "application" using the image schema and image data store as a valid option....) The image schema generation feature is covered in 5.3.1, “Generate Image Schema” on page 57.

2.2 Backward or Bottom-Up: Start with the Database

The backward or bottom-up path (Figure 11) is typical for a new application or application extension based on a given database.

There is no focus on real object-oriented modeling of the business, just easy and fast usage of the given database in the object oriented VisualAge development and deployment environment.

The first step is to capture the existing database implementation as a database schema in ObjectExtender. From then on all you have to do is click a button: generating a metamodel and mapping, business classes, and service classes. You can control every capture or generation step and make adjustments to the options as well as to the results produced by ObjectExtender.

20 Using VisualAge Smalltalk ObjectExtender

For situations beyond average requirements, such as complex table dependencies, absence of reference definition in the database, (performance related) redundancies in the tables, the captured and generated results require manual changes and adjustments.

ObjectExtender supports capturing the database implementation by importing the schema from the database.

Page 47: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

ServiceClasses

MetaModel

ModelClasses

DatabaseSchema

Mappings(Attr/Assoc)

Development Paths (in Relational DB Environment)

Generate Schema from Model(Mapping is generated too)

Database(DDL)

createTable...

RT RT

Export Schema to DB(Generate DB, Tables,...)

RT

Define ObjModel

GenerateModel Classes

GenerateService Classes

ImplementDatabase

Import Schema to DB(Generate Schema from DB)

Generate Model from Schema(Mapping is generated too)

GenerateModel Classes

GenerateService Classes

ImplementDatabase

Import Schema to DB(Generate Schema from DB)

Define ObjModeling

Map the Model to the Schema or vice versa

(3) Outside-In: Map the Model to the Database

(1) Forward or Top-Down: Start with the Model

(2) Backward or Bottom-Up: Start with the (Legacy) Database

B B B

Development Paths 21

Figure 11. Development Paths in a Relational Database Environment

GenerateModel Classes

GenerateService Classes

ObjectExtender Automated Tasks(Generation/Import/Export/...)

Manual Tasksin ObjectExtender

RuntimeComponentRT

Tasks Done in/bySome Other Tool(s)

DevelopmentComp. in BrowserB

Page 48: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

2.3 Outside-In: Map the Model to the Database Schema

The outside-in or mapping path offers the best options—clean object-oriented modeling and freedom in implementing the database—and is a combination of the top-down and bottom-up paths (Figure 11).

Mapping may become difficult, however: What do you do if you cannot find a reasonable mapping? You go back to your business object modeler and database designer to discuss alternatives, for which you can find reasonable mappings. If the database is given and already heavily used in other databases, an adaptive change of the database is not an option. The changes have to be made in the object model, the mapping, and the services. Changes in the object model and in the service requires some dedicated coding.

The Outside-In or mapping path is the best match for maintenance. Changes to an application require consideration on both ends, the business model end and the database end. Work must to be performed cautiously in a cooperative manner among business modelers, object modelers, implementers, and database designers and administrators. The model, schema, and map browser and editor facilities of ObjectExtender support implementers in making valuable proposals and doing the proof of concept of designs. The browsers provide nice and compact textual summaries for proposals and documentation (see 3.1, “Browsers” on page 23).

2.4 Whatever YOU Like

You can still go with the easy paths, but you must do the tasks step by step and manually. Running the tests manually gives you the most freedom in naming when defining the elements. ObjectExtender does its best to generate reasonable names. But you have to set up your conventions and adhere to them.

22 Using VisualAge Smalltalk ObjectExtender

Page 49: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 3. Tools

The VisualAge Smalltalk ObjectExtender tools are started in the System Transcript window through the ObectExtender Tools menu (Figure 12) as well as in almost every tool window.

Figure 12. VisualAge Smalltalk ObjectExtender Tools Menu

3.1 Browsers

In this section we provide a brief, pictorial overview of the browsers available with ObjectExtender. For further details see the VisualAge Smalltalk ObjectExtender User’s Guide and Reference.

© Copyright IBM Corp. 1999 23

Page 50: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

3.1.1 Model BrowserThe Model Browser (Figure 13) is used to create, select, and define a model. The text pane of the Model Browser shows a textual summary of the recently selected model element. The textual summary is visible in other tools also (see 3.3, “Smalltalk Class Editor and VisualAge Script Editor” on page 37).

24 Using VisualAge Smalltalk ObjectExtender

Figure 13. Model Browser: Model Rb01Employee

The model definition process is supported by the Class Editor (Figure 14 on page 25), Attribute Editor (Figure 15 on page 25), and Association Editor (Figure 16 on page 26), which you use to define new classes and edit existing

Page 51: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

classes. Class attributes can be added, amended, or deleted. Associations between different classes can be defined.

Figure 14. Class Editor: Class Employee

Tools 25

Figure 15. Attribute Editor: Attribute employeeNumber

Page 52: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 16. Association Editor: Association Department-Employees

Of note is the Lite Collections tab in the Class Editor (Figure 14 on page 25). Lite Collections are useful for retrieving a subset of the information from a particular object in the database without completely instantiating each object that is retrieved. This feature can improve performance when you retrieve large sets and sets of heavy rows (that is, rows with a lot of data). For further details about this feature, see the ObjectExtender User’s Guide and Reference and Chapter 17, “Lite Collections” on page 341.

26 Using VisualAge Smalltalk ObjectExtender

Page 53: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

3.1.2 Schema BrowserThe Schema Browser (Figure 17) is used to define the underlying physical data store.

Tools 27

Figure 17. Schema Browser: Schema Rb01Employee01 (Part 1 of 2)

Page 54: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 18. Schema Browser: Schema Rb01Employee01 (Part 2 of 2)

The Table Editor (Figure 19) and Column Editor (Figure 20 on page 30) provide facilities to add, delete, and edit column definitions in the table.

28 Using VisualAge Smalltalk ObjectExtender

Use Foreign Key Relationship Editor (Figure 21 on page 31) to define relationships between database tables. You specify which other tables provide foreign keys for the table and which columns in the table are foreign keys.

The various dialogs making up the Schema Browser provide entry fields for both the logical and physical names of tables, columns within tables, and foreign key relationships. The logical names should be chosen to be meaningful within the context of the application. If no physical names are entered, ObjectExtender uses the logical names as the physical names.

Page 55: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Note: When you enter physical names for your tables, columns, and foreign keys, you must take into account any limitations of the underlying database. For example, the DB2 database currently limits table and column names to 18 characters.

If you let ObjectExtender derive the physical names from the logical names, ObjectExtender makes useful truncations and solves duplicates by adding numbers. The maximum name length value can be set by executing the following Smalltalk code:

VapDatabasePhysicalRules maximumLength: 18.

Further customization of building physical names can be achieved through subclassing the VapDatabasePhysicalRules class.

Tools 29

Figure 19. Table Editor: Employee Table

Page 56: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 20. Column Editor: empno Column

Of note is the Converter of Type Details in Column Editor (Figure 20). A Converter defines how a column value is converted to an object and vice versa. For most column types the VapConverter default works fine, because ObjectExtender is able to derive the object class from the column type and vice versa. For Boolean, Charcter, and String objects the the VapCharToBoolean, VapCharToString, and VapTrimStringStringConverter are supplied. VapTrimStringConverter is the most appropriate converter for Strings, because it removes trailing blanks on reading from the database.

30 Using VisualAge Smalltalk ObjectExtender

Page 57: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 21. Foreign Key Relationship Editor: workDepartment

Tools 31

Page 58: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

3.1.3 Map BrowserThe Map Browser (Figure 22) is used to map the associations between the object model created with the Model Browser and the database schema created with the Schema Browser.

The Map Browser can also, on command, generate the initial code required for the Services layer.

32 Using VisualAge Smalltalk ObjectExtender

Figure 22. Map Browser: Map Rb01Employee (Part 1 of 2)

Page 59: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 23. Map Browser: Map Rb01Employee (Part 2 of 2)

In the Property Maps, two types of properties are shown (Figure 22 on page 32 and Table 1).

Table 1. Map Property Type Prefixes

Maps prefixed with an a represent attribute property maps between attributes in the object model and columns (Figure 24 on page 34).

Prefix Property Type

a attribute property

r association (relationship) property

Tools 33

Maps prefixed with an r represent associations (r stands for relationship) between interclass associations and foreign key relationships in the database schema (Figure 25 on page 34).

Page 60: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 24. Property Map Editor: Attributes

34 Using VisualAge Smalltalk ObjectExtender

Figure 25. Map Property Editor: Associations (Relations)

Page 61: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

3.1.4 Status Browser The Status Browser supplies a variety of useful functions. Figure 26 shows the View menu options.

Figure 26. Status Browser: View Menu

The most noteworthy options of the Cleanup and Activate menus are:

• Clear Home Collection Cache and Clear Relationship Cache. These two commands enable you to empty the caches that ObjectExtender builds up internally, to optimize database access times.

• Release All Transactions. This command ensures that there are no transactions active in the ObjectExtender system; all outstanding

Tools 35

transactions are discarded.

• Global ObjectExtender Reset. This command is sometimes necessary to restore ObjectExtender to a known state after errors have occurred during debugging.

• Activate Data Store. This is perhaps the most useful Status Browser command. Before a debug session can be started, it is necessary to establish a connection with the database. This command carries out the necessary connection initialization.

Page 62: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Most of the options can be invoked directly from Smalltalk scripts (see, for example, the commented script in 5.3.2, “Verify Local Image Schema and Data Store with Scripts” on page 58) and most have no dialogs. Errors throw exceptions that can be caught in the scripts. Some of the options are also available in the ObjectExtender Tools menu of the System Transcript (see below).

3.2 System Transcript

The System Transcript displays a log of the system operation (Figure 27). Its menus also provide a useful starting point for accessing the various services of the Smalltalk and ObjectExtender development environment.

36 Using VisualAge Smalltalk ObjectExtender

Figure 27. System Transcript with Log and ObjectExtender Tools Menu

Trace logging can be set on a packaged image, too, through a startup argument, either –vapBasicTrace or –vapDetailedTrace. The tracing is written to a log file whose location is defined with the –l parameter (A lower-case L, not the numeral 1).

Page 63: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

To start an image called ABT.ICX and set its tracing level to be a basic trace there is the command line argument:

ABT.EXE –iABT.ICX –vapBasicTrace –lC:\Temp\VapLog.TXT

Tracing an image can slow down performance because of the overhead of logging the information to the Transcript, a process that involves switching. This performance drop is typically significant, so use tracing during development to help understand the application while it is being built and debugged, but do not switch on tracing in packaged images unless an issue can be resolved by looking at the trace.

The ObjectExtender Tools menu shows a number of useful options. We recommend that you select the Basic Trace option as a minimum during development.

3.3 Smalltalk Class Editor and VisualAge Script Editor

ObjectExtender stores the definitions of the models, maps, and schemas not only as data in classes but also as textual summaries in the comment of the classes. Without starting a dedicated ObjectExtender tool, you can see the actual definition by looking at the comment of the storage class in the Smalltalk Class Editor VisualAge Script Editor (Figure 28 and Figure 29).

Tools 37

Figure 28. Smalltalk Class Editor Comment Showing the Textual Summary

Page 64: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 29. VisualAge Script Editor Comment Showing the Textual Summary

3.4 Inspectors

The Smalltalk inspectors still work as before, but "What you see is NOT what you get,..." at least sometimes, because of ObjectExtender’s optimization, caching, and transaction context dependencies (see also 5.7, “Do Some Smalltalk Inspection” on page 76).

Looking at the attribute values of a business object by examining the instance variables directly tells only half the story—as do the Smalltalk

38 Using VisualAge Smalltalk ObjectExtender

inspectors. Basically and simply for every new transaction created, a new object version with unset instance variables is created, like a temporary workspace in the new transaction. Values for the instance variables of the new created version in the new created transaction are retrieved from the version in the previous transaction, which was the context when the new transaction was created. Changes to the object in the context of the new transaction are effective only on the newly created object version.

On a commit of the new transaction, the new object version tries to merge its changed attributes with the attributes of the version of the previous

Page 65: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

transaction. If another transaction came first and merged first, the new transaction backs out with a rollback.

An object, created in the first created transaction retrieves and sets its instance value variables from the data object. The data object is read from the persistent storage. The object writes its instance values on a commit to the data object that is written to the persistent data storage.

For each instance variable, two kinds of setters and getters are created, for example, lastName: and lastName, and primLastName: and primLastName. The setters and getters with the prefix prim are the actual or primary instance variable accessors. Their code looks the same as the code of the usual setters and getters generated by VisualAge without ObjectExtender, except for some part of the getter code. The prim getter sets the instance variables after accessing the data objects for attributes and the persistent storage for associated business objects. Therefore only after a prim getter—and of course prim setter— invocation, the instance variable of an object shows the actual value. But you never, ever invoke the prim setters and getters from outside the object, because they are private methods. You use the ordinary—public—setters and getters, through which the prim setters and getters are applied on the right versions of the business objects.

The bad news is that the Smalltalk inspectors show only half the truth and you should not use them to set object instance variables. The good news is that the Smalltalk inspectors never intrude on the business objects.

You can find two versions of an ObjectExtender-oriented inspector extension among the downloadables (VapInspectorUtilitiesApp application in Appendix C, “Downloadables, ConfigMaps, Applications” on page 355). This extension enables the Smalltalk inspectors to look at and change the attributes of a business object.

The V0.1 [ JRW 08/28/98 ] a version of the inspector is not 100%

Tools 39

unintrusive to the objects it observes. The inspectors can look for the public setters and getters. On a read, public getters are fired and do a versionForRead lookup on the business object manager. If there is no version in the current transaction, one will be retrieved and possibly, depending on the repeatableRead status of the current transaction and its parent transaction, SQL locks will be established. Karl Werner Heisenberg’s Uncertainty Principle (cit. "What we observe is not nature itself, but nature exposed to our method of questioning." in Isaac Asimov’s Book of Science and Nature Quotations, ed. Jason Shulman & Isaac Asimov, 1988) is valid not only for observing atomic particles, but also for observing instance variables of business objects, when using this inspector extension version.

Page 66: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The version V0.2 [ JRW 09/07/98 ] a shows more technical information but is 100% unintrusive to the object it observes.

Loading either version of the inspector enablements into the image adds the Enable Inspectors choice to the ObjectExtender Tools menu (Figure 30). To control the enablement from Smalltalk, use this code:

VapInspectorUtilitiesApp enhancedInspectorsEnabled: aBoolean

Figure 30. ObjectExtender Tools Menu: Enable Inspectors Choice

40 Using VisualAge Smalltalk ObjectExtender

Page 67: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 4. Sample Scenarios

The examples in this book are derived from two scenarios:

1. The employee and department scenario

2. The library scenario

Appendix A, “Overview of the Examples in This Book” on page 351 lists all samples with content hints and the so-called project names. The project names are part of the VisualAge Smalltalk application names. The naming conventions are the subject of Appendix B, “Naming Conventions” on page 353.

When we developed the set of samples that we use in this book, we faced a special naming convention requirement. To use the same names for the classes in the sample implementations, you can have just one sample under development or loaded in just one image at a time. So you either unload the current sample to load another one, or you run separate images for each sample. For ease of use, however, we decided to use one image to hold all the samples. To differentiate the classes in the sample implementations, we prefix each sample and its contained classes and tables with an appropriate prefix, such as Rb20.

4.1 The Employee and Department Sample Scenario

The employee and department scenario has a system that maintains information about employees and departments of a company. This scenario is introduced in Chapter 1, “Concepts” on page 3 with class diagrams on page 3.

Part 2, “Your First Samples” on page 45 uses the employee and department scenario to familiarize you with the tools, frameworks, and development paths ObjectExtender. The sample sequence starts with just one class,

© Copyright IBM Corp. 1999 41

matching one database table, using the forward or top-down development path outlined in Chapter 2, “Development Paths” on page 19. Then, sample by sample, more complexity is added, such as transactions in GUIs, the backward or bottom-up development path, a second class, and a basic relation between the two classes.

The actual sample database delivered with DB2 provides a number of tables in addition to the basic Employee and Department tables (Figure 83 on page 107). However, for illustration purposes, the employee and department sample scenario uses just two classes (and their associated database tables);

Page 68: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

namely, the Department and the Employee classes. The relationships between these two classes are shown in Figure 2 on page 4.

Working with the employee and department sample scenario in Part 2, “Your First Samples” on page 45, you will develop a sound understanding of ObjectExtender’s tools, frameworks, and development paths—the bread and butter of ObjectExtender. But there is jam, too.

Part 3, “Advanced Details” on page 239 again uses the employee and department sample scenario to illustrate ObjectExtender’s support of handling mass data situations, such as binary large objects (BLOBs), large sets of heavy rows, and large objects.

4.2 The Library Sample Scenario

The library scenario has a system, that maintains the main business information of a library—Library Management System: Information about book titles, copies of these book titles, and customers who have books on loan.

The analysis of the library problem domain and the design of a library system is the subject of the IBM Redbook, Using VisualAge UML Designer, SG24-4997. VisualAge (Smalltalk) UML Designer is IBM’s object-oriented modeling tool to roundtrip engineer Smalltalk and forward engineer Java code.

Figure 31 through Figure 33 summarize the design of the Library Management System. For more details, for example the requirements, the use case descriptions, etc. see Appendix E, “Library Management System” on page 377.

Part 3, “Advanced Details” on page 239 recalls the library scenario and the design of the library system, and selects various aspects of it to show how to use ObjectExtender to make (the library) objects persistent in a relational

42 Using VisualAge Smalltalk ObjectExtender

database. It covers such topics as inheritance; hierarchical composition, such as a bill of material; many-to-many associations; user-defined selective queries; and nested and concurrent transactions.

Page 69: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 31. Library Management System: Overview

Sample Scenarios 43

Figure 32. Library Management System: Loan Management Use Cases

Page 70: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 33. Library Management System: Class Diagram

44 Using VisualAge Smalltalk ObjectExtender

Note: The status attribute—with the values available, borrowed, overdue, lost, and reserved—was removed from the Book (book copy) class and converted into the Status class hierarchy (Figure 33). The Status class hierarchy implements the state design pattern to make the loan part of the system a reusable framework.

Page 71: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Part 2. Your First Samples

© Copyright IBM Corp. 1999 45

Page 72: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

46 Using VisualAge Smalltalk ObjectExtender

Page 73: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 5. Employee Top-Down

The Employee Top-Down sample looks at just one class, the Employee class (Figure 34) and follows the forward or top-down development path.

Figure 34. Class Diagram Focusing on the Employee Class

For more information about the development path see 2.1, “Forward or Top-Down: Start with the Object Model” on page 19 and Figure 11 on page 21). The sample uses the name prefix Rb20.

5.1 Define the Model (Metadata)

< worksIn

isManagedBy >

isAdministeredBy >

Department Employee

* 1

*

1

0..1 0..1

employeeNumbernamephoneNumberworkDepartment...

departmentNumbernamemanageradminDepartment...

managedDepartment

manager

administrative

departments

workDepartment

employeeshas >

< administers

< manages

Department

© Copyright IBM Corp. 1999 47

The starting point for defining the model is the Model Browser. The model is defined in four stages as described below.

5.1.1 Create New ModelTo create and save a new model with the Model Browser (Figure 35), select Models->New Model... from the menu bar or New Model... from the Models list pop-up menu to create the new model. Then save the model by selecting Models->Save Model.

Page 74: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 35. Model Browser: Models Menu - New Model and Save Model

When asked for names, use the names listed in Table 2 or create your own names, consulting Appendix B, “Naming Conventions” on page 353.

Table 2. Model-Related Names for the Rb20Employee Sample

Creating and saving a new (empty) model adds the Rb20EmployeeModel to the list of (loaded) Models. Select the model and review its textual summary in the text pane (Figure 36).

Item Name

Model name Rb20Employee

Application name for storage (of the model) Rb20EmployeeModelApp

Class name for storage (of the model) Rb20EmployeeModel

48 Using VisualAge Smalltalk ObjectExtender

Figure 36. Model Browser: Textual Summary of New (Empty) Rb20Employee Model.

Page 75: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

A quick visit to the VisualAge Organizer window shows the newly created application and the associated storage class for the model (Figure 37).

Figure 37. Storage Application and Class for Rb20EmployeeModel

5.1.2 Define ClassesOnce you have the model defined, you can add classes. For this first sample, only one class is required: the Employee class. Again, in the Model Browser (Figure 38) select the Rb20Employee model and then select Classes->New Class... from the menu bar or New Class... from the Model Classes list pop-up menu to open the Class Editor.

Employee Top-Down 49

Figure 38. Model Browser: Classes Menu - New, Edit, and Delete Class

In the Class Editor (Figure 39) enter the new class name, Rb20Employee, and click on OK.

Page 76: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 39. Class Editor: New Rb20Employee Class

Figure 40 shows the Model Browser window after you have created the class and saved the model again.

Figure 40. Model Browser: Rb20Employee Model with (Empty) Employee Class

50 Using VisualAge Smalltalk ObjectExtender

5.1.3 Define AttributesTable 3 lists the attributes to define the Rb20Employee class.

Note that, to comply with Smalltalk naming conventions, the attribute names must start with a lower case letter. It is possible to argue, from a strictly data-driven approach, that the only required attribute is empNo, as it is the primary key. However, in deciding on what qualifies an attribute as “required,” we have taken a more business-oriented approach. Note further that the names are derived from the Employee table of the DB2 sample database (Figure 81 on page 105).

Page 77: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 3. Attributes of the Rb20Employee Class

To add attributes, in the Model Browser select the Rb20Model and the Rb20Employee class and open the Attribute Editor (Figure 42 on page 52) either directly or indirectly through the Class Editor.

To open the Attribute Editor:

• Directly: Select Attributes->New Attribute... from the menu bar or

Attribute Name Attribute Type Required Comment

1 birthDate Date No Birthdate

2 bonus ScaledDecimal No Bonus

3 comm ScaledDecimal No Commission

4 edLevel Integer Yes Education level

5 empNo String Yes (Object ID) Employee number

6 firstNme String Yes First name

7 hireDate Date No Hire date

8 job String No Job name

9 lastName String Yes Last name

10 midInit String Yes Middle initial

11 phoneNo String No Phone number

12 salary ScaledDecimal No Salary

13 sex String No Sex (M or F)

14 workDept String No Working department

Employee Top-Down 51

New Attribute... from the Class Attributes list pop-up menu (Figure 41).

• Indirectly through the Class Editor: Select Classes->Edit Class... from the menu bar or Edit Class... from the Model Classes list pop-up menu. In the Class Editor on the Attributes notebook page click on New... (see Figure 14 on page 25).

Page 78: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 41. Model Browser: Attributes Menu - New, Edit, and Delete Attribute

In the Attribute Editor (Figure 42 on page 52) specify attribute properties Name, Type, and Value required. Remember that to comply with Smalltalk naming conventions, the Name must start with a lower-case letter.

Figure 42. Attribute Editor: Attribute Named birthDate of Type Date

Figure 43 shows the Rb20Employee class with all attributes defined and the model saved. Note that not all attributes are shown in the Class Attributes

52 Using VisualAge Smalltalk ObjectExtender

list. Scroll through the attributes as well as through the textual summary to review the definition.

The textual summary shows a very significant item of information, Oid: Undefined, Which means that an object identifier has not been defined for this class. If at this point you try to generate the supporting model code, selecting Models->Generate... in the menu bar, you will get an error message saying that no object identifier has been defined.

Page 79: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 43. Model Browser: Rb20Employee Class with Attributes

You must define a suitable object identifier for the object. As noted in Table 3 on page 51, the attribute to be used as the object identifier is empNo. Use the Class Editor to select the empNo attribute and make it the object identifier (Figure 44). Once again, save the model when you have made these changes.

Employee Top-Down 53

Figure 44. Class Editor: Making empNo the Object ID of Class Rb20Employee

Page 80: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

5.1.4 Define RelationshipsThere are no relationships to be defined in this sample as there is only one class. You will see how to define relationships when we introduce the Department class.

5.2 Generate Code for the Model Classes

Before you generate the code for the model classes, you have to check the model generation options.

5.2.1 Set Model Code Generation OptionsIn the Model Browser select Models->Model Code Generation Options from the menu bar or just Model Code Generation Options from the Models list pop-up menu. Make sure that the correct model—Rb20Employee—is selected. The left-hand window in Figure 45 shows a sample model code generation options dialog.

Figure 45. Model Code Generation Options and Class Selection Dialogs

54 Using VisualAge Smalltalk ObjectExtender

The Model application name is the name of the application where ObjectExtender will store the generated code. ObjectExtender takes the model name Rb20Employee and appends ModelApp to create the default name, Rb20EmployeeModelApp. In a selection dialog at generation time you select the model classes for which you want to generate the code (right-hand window in Figure 45). These options are very convenient for large models and during maintenance. For large models it is preferable to store the code of each class or each reasonable cluster of classes in a separate application. During maintenance it is preferable to generate selectively—only for changed and new classes.

Page 81: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Because the Rb20 sample has only one class, there is no need to think about other names and clusters, but you do have to think about the ModelApp suffix. If you do not want to store the generated model code in the same application as you stored the model definition—and we suggest that you do not —change the suffix to App, so that the Model application name is Rb20EmployeeApp. (See the Note on page 354 in Appendix B, “Naming Conventions” on page 353).

The Generate VisualAge parts and Generate persistent classes options must be checked (as they are by default), Otherwise you will not get all of the generated code that you require later on for the sample.

The Default persistent class root option <default> defines BOWithDataObject as the root class for the generated model code class (see class hierarchy in Table 4).

Table 4. Class Hierarchy of Persistent Objects in ObjectExtender

Class Definition

Object nil subclass: #ObjectinstanceVariableNames: ’’classVariableNames: ’Dependents ’poolDictionaries: ’SystemPrimitiveErrors

SystemExceptions ’

BusinessObject Object subclass: #BusinessObjectinstanceVariableNames: ’bom ’classVariableNames: ’’poolDictionaries: ’VapExceptions ’

BOWithDataObject BusinessObject subclass: #BOWithDataObjectinstanceVariableNames: ’dataObject ’classVariableNames: ’’

poolDictionaries: ’’

Rb20Employee BOWithDataObject subclass: #Rb20Employee

Employee Top-Down 55

A development setup would usually define its own Default persistent class root class that has the BOWithDataObject as the superclass and contains the generic code common for all business objects. The class hierarchy in Table 5 includes such a Rb-framework default class root with the name RbBOWithDataObject.

instanceVariableNames: 'empNo lastName... job’'classVariableNames: ''poolDictionaries: ''

Page 82: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 5. Class Hierarchy of Persistent Objects in ObjectExtender

5.2.2 Start Model Code GenerationIn the Model Browser select Models->Generate... to start the model class code generation. In the selection dialog select the model classes for which you want to generate the code (right-hand window in Figure 45). Actually you deselect the model classes for which you do not want to create the code, because the dialog opens with all model classes preselected. Confirm your selection by clicking on OK and look at the trace messages in the Transcript window (Figure 27 on page 36).

If you now look at the VisualAge Organizer window and compare it with the Model Browser window in Figure 37 on page 49, you see, as shown in Figure 46, that (a new application and) new classes have been created for the model.

Class Definition

Object

BusinessObject

BOWithDataObject

RbBOWithDataObject inserted Rb-framework supeclass

Rb20Employee

56 Using VisualAge Smalltalk ObjectExtender

Figure 46. Code Application and Classes for Rb20EmployeeModel

Page 83: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Three new classes have been created:

• Rb20Employee. This class is the primary or business object class.

• Rb20EmployeeHome. This class is a helper class responsible for retrieving, holding existing, and creating new instances of the Rb20Employee class.

• Rb20EmployeeKey. This class is responsible for administering the object identity attribute.

5.3 Generate Schema and Mapping (Metadata and Database)

If you want to run the sample with the database simulated in your image, continue with 5.3.1, “Generate Image Schema” on page 57. If you have DB2, or an equivalent ODBC database installed on your system and connected to the VisualAge Smalltalk integrated development environment (IDE), you can use it now by going to 5.3.4, "Generate Database Schema," on page 61 or after you have checked out the persistence of your model with the image schema.

5.3.1 Generate Image SchemaThe purpose of using the image as the database is to simplify the (early) development stage: immediate testing is possible, no database definitions and alterations are required, you do not interfere with other developers, and sample test data sets can be saved to and loaded from files.

To generate the image schema use the Model Browser and select Models-> Generate Image Schema... from the menu bar (Figure 35 on page 48). In the model class selection dialog confirm the selection by clicking on OK (Figure 47).

Employee Top-Down 57

Figure 47. Class Selection Dialog when Starting the Generation

Page 84: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Take a look at the VisualAge Organizer to see the service application and service classes ObjectExtender generates for the image schema (Figure 48).

Figure 48. Image Schema Application and Service Classes

Because the image schema generation completes all work up to the access of the image data store, no further work is required to get ready for testing.

5.3.2 Verify Local Image Schema and Data Store with ScriptsRun the script sequence presented below. It leads you in 15 steps through a verification scenario. The scripts are saved in the Rb20LIS.wsp workspace of the downloadables (see Appendix C, “Downloadables, ConfigMaps, Applications” on page 355.) For each step swipe over the lines through the line with the dashed arrow (--->) at the end and execute the selection. The output of the system is shown in italics. Activate the detailed trace in the System Transcript by selecting ObjectExtenter Tools->Detailed Trace.

58 Using VisualAge Smalltalk ObjectExtender

"01 Perform a global reset of ObjectExtender"System vapReset " --->"*** Resuming ->{0}(Shared)( > 28578)

"02 Activate the Rb20EmployeeHome’s data store"Rb20EmployeeDataStore singleton activate " --->"

"03 Clear the local image data store"ImageServiceObject reset " --->"

Page 85: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

"04 Ask the Rb20EmployeeHome for all instances"Transcript cr; show:

(Rb20EmployeeHome singleton allInstances) printString; cr"returns an empty OrderedCollection --->"’>>>executing allInstances’OrderedCollection()

"05 Create and make persistent a new instance in a Transaction"’1stTransaction’. "... just a transaction name"Rb20EmployeeHome singleton create

empNo: '100001';firstNme: 'David'; midInit: 'A'; lastName: 'Singleton'edLevel: 9; job: 'ObjectExtender Specialist'.

Transaction current commit " --->"*** Resuming ->{0}(1stTransaction)( > 22792)*Committing* {1}(1stTransaction)( > 22792 > 7044)2w’>>>executing insert’>>>>committing

"06 Ask the Rb20EmployeeHome for all instances"Transcript cr; show:

(Rb20EmployeeHome singleton allInstances ) printString; cr"returns an OrderedCollection with the instance with empNo=’100001’ --->"’>>>executing allInstances’OrderedCollection(a Rb20Employee(’100001’) )

"07 Save the local image data store to the file Rb20Emp1.lis"ImageServiceObject save " --->"

"08 Clear the local image data store"ImageServiceObject reset " --->"

"09 Ask the Rb20EmployeeHome for all instances"Transcript cr;

show: (Rb20EmployeeHome singleton allInstances ) printString; cr"returns an empty OrderedCollection --->"’>>>executing allInstances’OrderedCollection()

Employee Top-Down 59

"10 Load the local image data store from the file Rb20Emp1.lis"ImageServiceObject load "--->"

"11 Ask the Rb20EmployeeHome for the instance with key=’100001’(Do it in a transaction to perform an update)"| employee |Transaction begin: ’2ndTransaction’.employee := Rb20EmployeeHome singleton findByEmpNo: ’100001’.Transcript cr; nextPutAll: employee firstNme.employee firstNme: ’Jonathan’.Transcript nextPutAll: ’ ---> ’; nextPutAll: employee firstNme; cr.Transaction current commit

Page 86: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

"returns the instance with empNo=’100001’ and updates firstNme --->"*** Resuming ->{0}(2ndTransaction)( > 17826)David ---> Jonathan*Committing* {1}(2ndTransaction)( > 17826 > 7044)

"12 Ask the Rb20EmployeeHome for the instance with key=’100001’(Do it in a transaction to perform a delete)"| employee |Transaction begin: ’3rdTransaction’.employee := Rb20EmployeeHome singleton findByEmpNo: ’100001’.Transcript cr; nextPutAll: employee firstNme; cr.employee markRemoved.Transaction current commit"returns the instance with empNo=’100001’ and removes the instance --->"*** Resuming ->{0}(3rdTransaction)( > 25656)Jonathan*Committing* {1}(3rdTransaction)( > 25656 > 7044)

"13 Ask the Rb20EmployeeHome for the instance with key=’100001’Rb20EmployeeHome singleton findByEmpNo: ’100001’"returns nil, because the instance with key=’100001’ was removed --->"’>>>executing find by key’nil

"14 Clear the local image data storeImageServiceObject reset " --->"

"15 Perform a global reset of ObjectExtender"System vapReset " --->"*** Resuming ->{0}(Shared)( > 28578)

5.3.3 Version, Release, and Save the Sample WorkAt this point, we suggest versioning and releasing (and saving by exporting) the sample work you have done so far, especially if you want to continue with 5.3.4, “Generate Database Schema” on page 61:

60 Using VisualAge Smalltalk ObjectExtender

1. Version and release all classes2. Version all applications3. Create a new configuration map (Rb20EmployeeLISConfigMap)4. Add all versioned applications to the new configuration map5. Version the new configuration map6. Export the versioned configuration map as a save. (We exported our

configuration map to file Rb20LISD.dat; see Appendix C, “Downloadables, ConfigMaps, Applications” on page 355).

If you do not have a database system installed, or if you want to go on with the image schema, continue with 5.5, “Activate a Data Store” on page 71.

Page 87: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

5.3.4 Generate Database SchemaIn 5.3.1, “Generate Image Schema” on page 57 we use an in-image database. In this section we demonstrate the use of a physical database, with the IBM DB2 database. Although DB2 comes with the relevant Employee table, for the purposes of this example, we assume that it is necessary to generate the tables from scratch.

Note: Before you continue, version and release (and save by exporting) the sample work you have done so far, and—if you generated the local image schema—perform an Activate->Clear local image data store and a Cleanup->General ObjectExtender reset in the Status Tool/Browser. To version and release (and save) your sample work, follow the steps in 5.3.3, “Version, Release, and Save the Sample Work” on page 60. You actually do not have to unload Rb20EmployeeServicesApp for the local image data store because the services application for database data store will be called differently.

The relevant model, Rb20Employee, already exists. The next stage is to generate a schema and map from the model. In the Model Browser select Models->Generate schema from model from the menu bar.

Note: ObjectExtender generates both the schema and the corresponding map.

ObjectExtender derives the logical names for the schema entities from the model entities, chooses VAP for the (high-level) table qualifier, VapConverter for the column data converter, and VARCHAR(12) for the column type for all String-attribute-related columns. To verify the schema, open the Schema Browser (Figure 49) by selecting ObjectExtender Tools-> Browse Schemas from the menu bar in, for example, the System Transcript Select schema Rb20Employee in the Schemas list and browse the textual summary of the schema in the bottom pane of the browser. Select table Rb20Employee from the Tables list to list the columns

Employee Top-Down 61

with their specifications in the Columns list.

ObjectExtender’s choices, namely, VAP, VapConverter, and VARCHAR(12) are technically correct and work (almost) perfectly, but they do not exactly reflect the environment, user interface, and business needs. For all characterlike columns use the VapTrimStringConverter converter to get the usual string concatenation and entry field behavior in today’s GUIs—except the data is sensitive to leading and trailing blanks and must be processed as is.

In the Schema Browser select the Rb20Employee schema and the Rb20Employee table and then select Tables->Edit Table... to open the

Page 88: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table Editor and change the high-level qualifier, VAP, to USERID, our choice (Figure 50). The qualifier is a standard DB2 access qualifier (typically the name used to log on to the DB2 database). If you are unsure of which qualifier to use in your environment, consult your database administrator.

62 Using VisualAge Smalltalk ObjectExtender

Figure 49. Generated Schema Rb20Employee

In the Table Editor select a column and click on the Edit... button to open the Column Editor and change the column’s Type, Converter, and Length. You can also open the Column Editor on a Columns from the Schema Browser by double-clicking on the column in the columns list... or by selecting the column and choosing Columns->Edit column... from the menu bar.

Page 89: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 50. Table Editor: Rb20Employee

Use the information listed in Table 6 to change the columns (in bold). The proposed column types and lengths have been chosen to match those in the employee table in the DB2 sample database.

Table 6. Columns for the Rb20Employee Table

Column Name

Column Type with Length

Not Null

Column Name

Column Type with Length

Not Null

Employee Top-Down 63

1 birthDate DATE No 8 job CHAR(8) No

2 bonus DECIMAL(9,2) No 9 lastName VARCHAR(15) Yes

3 comm DECIMAL(9,2) No 10 midInit CHAR(1) Yes

4 edLevel SMALLINT Yes 11 phoneNo CHAR(4) No

5 empNo CHAR(6) Yes 12 salary DECIMAL(9,2) No

6 firstNme VARCHAR(12) Yes 13 sex CHAR(1) No

7 hireDate DATE No 14 workDept CHAR(3) No

Page 90: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 51. Column Editor: Column empNo of Rb20Employee Table

After changing the qualifier and the columns, save the schema. In the Schema Browser select Schemas->Save Schema... from the menu bar. Use Rb20EmployeeSchemaApp for the application and Rb20EmployeeSchema for the storage class.

As mentioned before, the map was generated together with the schema. Because type changes of columns do not affect mappings, and the mappings are OK, only the map has to be saved—after a review.

64 Using VisualAge Smalltalk ObjectExtender

To review the map, open the Map Browser (Figure 49) by choosing ObjectExtender Tools->Browse Maps from the menu bar in, for example, the System Transcript. Select map Rb20EmployeeRb20Employee in the Maps list and browse the textual summary of the map in the bottom pane of the browser. Select the Rb20Employee class in the Persistent Classes list and the Rb20Employee (primary) map in the Table Maps list to review the mappings in the Property Maps list. The lower-case a in parentheses indicates an attribute mapping (see Table 1 on page 33). ObjectExtender generates by default a Simple mapping (see the Property Map Editor in

Page 91: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 24 on page 34). The name in parentheses is the (logical) column name to which the attribute (or association) is mapped.

Employee Top-Down 65

Figure 52. Map Browser: Rb20Employee Map

Note that none of the attributes is part of the optimistic predicate. The optimistic predicate is used in the optimistic locking of a persistent class to detect—by a read and compare before write—an update concurrence conflict—Last comes, last wins. The business rules and the business processes would define the critical attributes (and associations), which then become candidates. A generic approach to protect against overwriting is to define a time stamp or update counter attribute and declare it as the only part of the optimistic predicate. ObjectExtender chooses optimistic locking by default. Pessimistic locking can be enabled by choosing

Page 92: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Persistent Classes->Enable pessimistic locking on a selected persistent class in the Map Browser.

Note further that ObjectExtender concatenates the name of the model name and the name of the schema to create the name of the map. If you create the map manually, you may prefer to use just the "Project" name, Rb20Employee, as listed in Appendix B, “Naming Conventions” on page 353.

In the Map Browser select Datastore Maps->Save Datastore Map to save the map. Use Rb20EmployeeMapApp for the application name and Rb20EmployeeMap for the storage class. Storing the map in the same application as the schema is a valid alternative.

5.3.5 Generate the DDL and the Database TablesIt is possible to view the DDL code that the Schema Browser would use to create the physical database tables (Figure 53).

66 Using VisualAge Smalltalk ObjectExtender

Figure 53. DDL to Create the Rb20Employee Table

Page 93: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

There are several ways of generating the physical database tables. For example, it would be possible to copy and paste the DDL script displayed in the Schema Browser window into a text file and then run the text file from a DB2 command window. However, perhaps the simplest way is to get the Schema Browser to do the work itself. In the Schema Browser (Figure 82 on page 106) select Schemas->Import / Export Schema-> Export Entire Schema to Database. When the Schema Browser executes this command, it asks for the database connection information as shown in Figure 54. Use the relevant parameters given to you by your database administrator.

Note: For the RedBook ObjectExtender samples we created the RBOE database, added the system-defined user USERID (with password PASSWORD), and granted it all rights. Watch for the case of the password! Some systems are case sensitive To create the database in DB2 (UDB, Version 5): Start the Command Center program, open a Control Center with the hierarchy tool button, expand the hierarchy and work with the popup menus on the hierarchy items; for example, on the DB2 item select Start from the pop-up menu to start DB2, or on the Databases item select Add...from the pop-up menu to add a database and so on. If you need to start or stop a DB2 administration server, in a system command window use DB2ADMIN START or STOP. You also can start or stop DB2 in a system command window with DB2START and DB2STOP.

Employee Top-Down 67

Figure 54. Database Connection Dialog

When you click on the OK button, the Schema Browser establishes the necessary database connection, creates the tables, and makes the alter for

Page 94: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

the key. The result of creating the database is displayed in the System Transcript window (Figure 55).

68 Using VisualAge Smalltalk ObjectExtender

Figure 55. System Transcript Showing Results of Creating the Database

Figure 55 shows that an error occurred during the schema creation. However, with a little more thought, this error is to be expected. The Schema Browser issues a Drop Table... command before the Create Table... command, just in case the table already exists. This is relatively standard with such scripts, and you can safely ignore the error message.

Page 95: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

5.4 Generate Service Classes

In 5.3, "Generate Schema and Mapping (Metadata and Database)," on page 57, we created the schema for an in-image database and for a physical database hosted by DB2. For the in-image database, the service classes were created automatically as part of the in-image database creation. For the physical database case, you have to create the service classes in a separate task. Using the Map Browser follow the steps described below.

5.4.1 Set the Service Code Generation OptionsIn the Map Browser select Datastore Maps->Generation Options... to check the service generation options (Figure 56).

Figure 56. Service Code Generation Options for DB2 Database

When the dialog is first presented, the Database connection info field is likely

Employee Top-Down 69

to be blank. Use the Change button to establish an automatic connection with the database, as in Figure 54. If you leave the field blank or specify the information only partly, you are prompted for the missing information at runtime—when using the services or connection the first time. We accepted the default proposal for the Services application name, but you can use another name if you prefer.

Note that you do not have to save the map, even though you changed the services code generation options. The options are only transient and not part of the map.

Page 96: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

5.4.2 Start Service Code GenerationTo start the generation of the code for the service classes, select Datastore Maps->Generate Services from the menu bar in the Schema Browser. When this operation is complete, you are ready to test the sample without developing a GUI.

Use the VisualAge Organizer to see the applications and classes generated for the services (Figure 57).

Figure 57. Services Generated for Rb20Employee and DB2

Note that the name of the data store for the database is different from the name of the data store for the local image schema. The database data store

70 Using VisualAge Smalltalk ObjectExtender

name is derived from the map name—a concatenation of the model and schema name. The local image schema data store has no map and no dedicated schema—it uses a generic schema, so the data store name consists only of the model name because there is no other name from which to derive it.

Page 97: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

5.5 Activate a Data Store

In Chapter 1, “Concepts” on page 3 you were introduced to application layers and persistence layers (Figure 3 on page 5 and Figure 4 on page 6). Both layers have a similar pattern to successfully separate the model from the storage. Now, we want to make the model code, without changing it, talk and listen to various data stores. How can we do that? By activating a data store. But how do the homes, that is, logical storage, know about the data store and vice versa? In the generation process, first the model code is generated—with a special focus on the homes. Then with the knowledge of the homes, the services sets are generated, such as the services for the local image or the database and—the most important—the data store, which is the physical storage.

Selecting and activating a data store is like connecting the logical storage—the homes—with the physical storage—the data store (Figure 58).

HomeCollections

ServicesSets

of aModel

Activate Data Store

Employee Top-Down 71

Figure 58. Conceptual View of Activating a Data Store

Data Stores

ImageSchema

Relational DatabaseSchema

Stub/...Schema

Page 98: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

At runtime, when the data store is activated, the activate method shown in Figure 59 is invoked. The activate method is implemented in the abstract DataStore class and inherited by all concrete data store classes.

Figure 59. DataStore>>#activate Method

The last three lines assign the data store and services to the home,— and the last five lines assign the homes to the data store.

From the above discussion we can conclude that many data stores can be in the image for one and the same model, but only one of them can be active at a time.

To actually activate a data store execute one of the following Smalltalk expressions:

• XyzAbcDataStore singleton activate

• VapBrowserSupport vapActivateDataStore

The latter expression can be used only at development time.

AnyDataStore(DataStore)>>#activate

>>>

activate

"Set up the home collections we service."

self initializeSessionPool.homeCollections := LookupTable new.self currentHomes with: self serviceObjectClasses do: [

:eachHome :eachServiceObject |homeCollections

at: (eachHome class name asString)put: ( eachHome

dataStore: self; "<---- the very data store"serviceObjectClass: eachServiceObject) ]

72 Using VisualAge Smalltalk ObjectExtender

5.6 Run Sample Headless with Scripts

In this section, we explore the use of the ObjectExtender development environment to test the object class without developing a GUI (that is, run the sample headless). You may believe (as we believed at first) that developing a GUI is the simplest way to test a class. However, running the sample headless enables you to see the system in operation and understand it better than would be possible with a GUI.

Page 99: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

To run the sample headless, you need a Smalltalk window in which you can type text. You can use any of the script editing windows but it is a lot simpler and easier to use a workspace window. In the VisualAge Organizer (or almost any Smalltalk window), select the File->New Workspace (or File->New) from the menu bar to open a new workspace window. Save the contents from time to time to a file to keep your work for reference and reuse. See the printout of our workspace with the system replies included, in Appendix D.1, “Rb20HDL.wsp - Headless Test Workspace” on page 361. For the downloadable file, see Appendix C, “Downloadables, ConfigMaps, Applications” on page 355.

5.6.1 Run Scripts StepwiseType the following Smalltalk code into the window, select it with the cursor, click the right-hand mouse button, and select the Inspect command:

self halt.Rb20EmployeeHome singleton allInstances

The first line opens the debugger window, as shown in Figure 60. Using the debugger in this way, you can step through the code and see what happens at each stage.

Employee Top-Down 73

Figure 60. Debugger Stopped on “self halt.”

When you click on the Resume button, you are likely to be presented with an error message telling you that ”There is no active data store for a Rb20EmployeeHome.” In this case, you must activate the data store by using the Activate->Activate Data Store command in the ObjectExtender Status Browser or by executing on of the following Smalltalk expressions:

Page 100: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Rb20EmployeeDataStore singleton activate "for the image data store"

Rb20EmployeeRb20employeeDataStore singleton activate "for the DB d.s."

VapBrowserSupport vapActivateDataStore "you are aksed what data store"

(ObjectExtender named the data store Rb20EmployeeDataStore when the image schema (and services) were generated, and Rb20EmployeeRb20employeeDataStore when the database schema (and services were generated.)

See 5.5, “Activate a Data Store” on page 71 for more information about the relationship between data stores and homes.

Inspecting the result of the Rb20EmployeeHome singleton allInstances expression shows that an OrderedCollection is delivered. Further inspection of the contents of this OrderedCollection shows that there is no data in the database. This is not surprising as the database has been created from scratch and is therefore empty.

The next stage is to populate the database. As discussed in 1.3, “Transactions” on page 11, a transaction is necessary to handle the interaction with the database. The following code snippet inserts a single record into the database (only the values for the mandatory fields are used):

Transaction begin.Rb20EmployeeHome singleton create

empNo: ’A12345’;firstNme: ’Fred’; midInit: ’Q’; lastName: ’Smith’;edLevel: 18.

Transaction current commit.

You can once again inspect the result of the Rb20EmployeeHome singleton allInstances expression. This time, the OrderedCollection inspector shows that our database now contains one record, as illustrated in Figure 61.

74 Using VisualAge Smalltalk ObjectExtender

Figure 61. Result of Making a Single Employee Object Persistent

Page 101: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

When you use a DB2 database, you can also use the standard DB2 command environment to see what is in the database.

It would be quite useful to be able to see what our object actually contained in the way of attributes. This is discussed further in 5.7, "Do Some Smalltalk Inspection," on page 76.

5.6.2 Monitor Headless Sample with Status BrowserAt this point, we recommend that you use the Status Browser to explore the options available for displaying status information for the sample that we have just created, so that you are familiar with what is displayed. The available outputs are too numerous to describe here in detail; however, two important facilities are offered by the Status Browser.

• On the Cleanup menu, the following commands (whose names are self-explanatory) are useful for partially or completely resetting the system during testing:

• Clear Home Collection Cache... • Clear Relationship Cache... • Reset Data Store... • Release All Transactions • Global ObjectExtender Reset

• On the Activate menu:

• Activate Data Store. The use of this command has already been covered. All data stores must be activated before they can be used.

• Load Local Image Data Store. This command allows a previously saved copy of the local image data store to be reloaded into the image data store.

• Save Local Image Data Store. This command allows a copy of the local image data store to be written to a separate file so that it can be reloaded in the future (for example, for testing).

Employee Top-Down 75

• Clear Local Image Data Store. This command empties the local image data store of all its contents.

Further information is available in the ObjectExtender help files.

Page 102: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

5.7 Do Some Smalltalk Inspection

ObjectExtender does some tricky things with the basic inspection such as:

Now you see me, now you don’t!

This next section will give you a good understanding of why inspecting persistent objects in a transaction-oriented environment is different from inspecting transient objects.

The example was developed with the DB2 database, so you can inspect the table contents through the DB2 command line interface. Sometimes looking at the image and the database at the same time can be very useful for debugging. However, understanding this section is not necessary for understanding subsequent sections. You may want to proceed directly to 5.8, “Create Views with Transactions” on page 83.

5.7.1 Use the Basic Smalltalk Inspector (#inspect)In (5.6, "Run Sample Headless with Scripts," on page 72), we use a script to insert a single object into our database. Now we want to use the VisualAge tools to inspect that object so that we can understand how the ObjectExtender persistence framework operates.

The inspect example uses the script presented below. The halts are built in to let you look at the results that we want to discuss. Clicking on the Resume button in the debugger will bring you to the next result. You do not have to worry about opening or closing the inspectors and debuggers; the script does that for you automatically. (The only thing you might have to do is move the debugger window, to see the inspector window.)

"01" | employee |"02" System vapReset."03" Rb20EmployeeDataStore singleton activate."04" Transaction begin.

76 Using VisualAge Smalltalk ObjectExtender

"05" employee := Rb20EmployeeHome singleton allInstances first."06" (DbgInspector on: employee) open; halt; close."07" (DbgInspector on: employee lastName) open; halt; close."08" (DbgInspector on: employee) open; halt; close."09" Transaction current commit

The steps in this inspection example are these:

1. Declares a temporary variable employee

2. Carries out a global ObjectExtender reset

Page 103: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

3. Activates the Rb20EmployeeDataStore

4. Begins a transaction

5. Sets the temporary variable to the first (the one and only) item in the database

6. Inspects the temporary variable. The result you get should be similar to that in Figure 62. To show the values, select all instance variables by swiping over the list while holding down the (selection) mouse button.

Figure 62. First Inspection of the Attributes through the Instance Variables

Note that the only attribute that appears to be set is that used for the object identifier, empNo. At first view, this is rather surprising. The explanation is that ObjectExtender uses concept called lazy read and lazy set, and the standard debugger that is usually used in Smalltalk does not know anything about it. The debugger displays only the values of the instance variables. ObjectExtender holds a physical record read from the database but does not set the object instance variables until required.

7. Inspects the lastName attribute. Smith, the lastName we entered, is displayed, (Figure 63).

Employee Top-Down 77

Figure 63. Inspecting an Attribute through the Getter

Page 104: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

8. Repeats step 4. This time, as shown in Figure 64, lastName has a valid value.

Figure 64. Second Inspection of the attributes through the Instance Variables

The other instance variables that were set (for example, edLevel) are still shown as nil, as they have not been individually accessed. Repeating step 5 for the other attributes would result in their values being shown when the Employee object is once again inspected.

9. Terminates the transaction with a commit.

5.7.2 Use the ObjectExtender Enablement for the InspectorsImport the V1.0 [ JRW 08/28/98 ] a version of the VapInspectorUtilitiesApp in the downloadable RBOEZD.DAT library into your library and load it into your image (see Appendix C, “Downloadables, ConfigMaps, Applications” on page 355). Enable the inspectors by selecting ObjectExtender Tools-> Enable Inspectors in the System Transcript (Figure 30 on page 40). Repeat the script in 5.7.1, “Use the Basic Smalltalk Inspector (#inspect)” on page 76 with the enabled inspectors and compare the inspector windows you

78 Using VisualAge Smalltalk ObjectExtender

get with the disabled inspectors.

For example, the enabled inspector in Figure 65 shows the values of the set instance variables (empNo, firstName, midInit, lastName, edLevel), whereas the disabled inspector in Figure 62 on page 77 shows only nils. Furthermore, the enabled inspector hides the ObjectExtender instance variables of the business object (bom and dataObject).

Page 105: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 65. Enabled Inspector Showing the Values of the Instance Variables

As explained in 3.4, “Inspectors” on page 38, the enabled inspectors access the attributes of a business object through public getters and setters. Business logic is executed, the persistent values are read and set, ...and the business object is—or at least behaves—"changed."

5.7.3 Look at All Instances of a Class (#allInstances)It is now instructive to change the value of one of the attributes and see what happens. Use the script presented below, which behaves just like the script in 5.7, “Do Some Smalltalk Inspection” on page 76. Again, just look at the opening inspectors, and then continue by clicking on the Resume button in the debugger. You do not have to close the inspector or debugger windows that open automatically. Note: Disable the inspector enablement in the ObjectExtender Tools menu of the System Transcript to get the windows that match Figure 66 through Figure 70.

"01" | employee |"02" System vapReset."03" Rb20EmployeeDataStore singleton activate.

Employee Top-Down 79

"04" Transaction begin."05" (DbgInspector on: Rb20Employee allInstances) open; halt; close."06" employee := Rb20EmployeeHome singleton allInstances first."07" employee firstNme."08" (DbgInspector on: Rb20Employee allInstances) open; halt; close."09" employee firstNme: ’Mike’."10" (DbgInspector on: Rb20Employee allInstances) open; halt; close."11" Transaction current commit."12" employee := nil."13" (DbgInspector on: Rb20Employee allInstances) open; halt; close

Page 106: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The steps in this allInstances of a Class sample are:

1. Declares a temporary variable employee

2. Carries out a global ObjectExtender reset

3. Activates the Rb20EmployeeDataStore

4. Begins a transaction

5. Inspects allInstances of the Employee class

The inspector displays an array with the number of instances of the Rb20Employee class that have been instantiated and are now held in the Smalltalk image. The display should show that no instances have been instantiated (Figure 66). Note that this allInstances method is actually implemented in the Behavior class, a class very far down within Smalltalk. Do not use it within your normal code as it will conflict with the way that ObjectExtender handles persistent objects.

Figure 66. Initial Result of Rb20Employee allInstances: No Instances

If the display shows that some instances are present (and this happened to us once), the instances are probably held by some dangling reference. To get rid of them, follow these steps:

1. Close all windows with potential references—debuggers and inspectors too—and get rid of all globals you might have used for testing and check class variables that might be direct or indirect references.

80 Using VisualAge Smalltalk ObjectExtender

1. Use the ObjectExtender Status Tool/Browser menu options or the corresponding Smalltalk expressions, such as

• Transaction reset • System vapReset

2. If this does not help, use this expression

• System abtScrubImage

Note: Never, ever, use the expression you used to use in the plain Smalltalk world: AClass allInstances do: [:each | each become: nil]. You

Page 107: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

must forget that you have ever seen it. Using this "ugly" piece of code is certain to mess up your image and ObjectExtender’s object bookkeeping.

6. Sets the temporary variable to the first item in the database

7. Accesses the firstNme attribute firstNme through the getter

8. Repeats step 5. Inspects the number of instances of the Rb20Employee class that have been instantiated in step 6. The display (Figure 67) shows that there is one instance of the class, and the lastName instance variable shows a value different from nil. (To see the values of the Employee object, double-click on the number 1 and select the entries by swiping over them while holding down the (selection) mouse button.)

Figure 67. Result after One Read and an Attribute Access

9. Changes firstNme to ’Mike’

10.Repeats step 5 again

The code inspects the number of instances of the Rb20Employee class that have been instantiated in step 6 and changes one attribute through the setter in step 9. This time there are two instances (Figure 68).

Employee Top-Down 81

Figure 68. Two Instances After an Update to an Attribute.

Page 108: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

At first sight this is somewhat surprising. We have changed frstNme and suddenly we have two copies of the same object! This is the ObjectExtender persistence framework at work. Figure 69 shows the contents of the original object, read from the database, and Figure 70 on page 82 shows the contents of the changed object. In both cases, all instance variables that were previously set when the database record was created have now been set and displayed.

Figure 69. Object with Original Attribute Values

82 Using VisualAge Smalltalk ObjectExtender

Figure 70. Object with Changed Attribute Values.

Page 109: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The surprising thing in Figure 69 on page 82 is that firstNme is still Fred. After all, we have just changed firstNme to Mike. However, Figure 70 shows the attributes in the second instance, and here, firstNme is Mike.

The reason for the difference is quite simple. The persistence framework is working. The transaction is not committed, so the framework needs to keep two instances of the object. The first instance is the one that was read from the database, with the original firstNme, "Fred." Perhaps another transaction will need to access the object and, as the change has not yet been committed, that second transaction must get the original copy. The second instance is the updated version with the new firstNme, "Mike."

11.Commits the transaction

12.Clears the temporary with nil (releases the object)

13.Repeats step 5 again. Inspects the number of existing instances—1—as in Figure 67 on page 81, but with the new firstNme.

5.8 Create Views with Transactions

In previous sections, for example, in 5.5, “Activate a Data Store” on page 71 and 5.6, “Run Sample Headless with Scripts” on page 72 we cover interacting with the database through scripts. However, it does not take much to set up a nice GUI to run the sample. In this section we present four views. They all use the same GUI part but attach to the transaction framework in two different ways, as described below.

5.8.1 Use the Basic Transaction PartsFigure 71 shows the Rb20EmployeeView1—the first and only version—that attaches to the transaction framework by using the basic transaction parts sharedTransaction and topLevelTransaction.

Employee Top-Down 83

Page 110: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 71. Employee View1 Using the sharedTransaction and topLevelTransaction

The key features of this version are listed after the parts list shown in Figure 72, on the left. Detailed connection information is listed in Table 7 on page 88. The connections are made following the guidelines set in the

84 Using VisualAge Smalltalk ObjectExtender

ObjectExtender User’s Guide and Reference.

Page 111: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 72. Parts List of the Rb20EmployeeView 1, 2 and 4, and 3

Employee Top-Down 85

The key features of Rb20 EmployeeView are:

• A Window with:

• A container with columns to show the most significant attributes of all instances in a scrollable list (containerEmployees). In a real application, the list would show only a user preselected collection.

• Entry fields in a scrollable form (scrolledForm) to allow a new or selected employee to be edited (...Fields for the attributes—not shown in Figure 72—are in empDetailForm, the only contents of the scrolledForm).

Page 112: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The entry fields are all text entry fields, but appropriate converters have been selected in the Open Settings dialogs for each field to handle conversion between strings and the underlying database type (such as date). It would be possible to use a combo box, for example, for the sex field, as a combo box has only two allowable values, M and F. However, we need to use this field to demonstrate some problems and their solution, and that is not possible with a combo box.

• Buttons to create a new employee entry and to reset, save, or delete entries (pbNew, pbReset, pbSave, and pbMarkForDelete).

• An employeeHome to manage the collection and creation of Employee objects

• The sharedTransaction systemwide for the overall transaction control.

• A topLevelTransaction to handle each individual database transaction. The rootCommittedOrRolledback event is connected to the beginChild: action of the sharedTransaction. The normalResult event of this connection is in turn connected to the self action of the topLevelTransaction. In this way, whenever a transaction completes or rolls back, another one is created. We need to use the rootCommittedOrRolledback event so that we also generate a new transaction if the current transaction is rolled back when the Reset button is clicked or a transaction fails. The rootCommittedOrRolledback event is also connected to the container items action, with employeeHome allInstances as a parameter, to refresh the list.

• A transacted employee variable to hold the current employee details. It is important to note that there is a connection between the transaction attribute of the employee and the self attribute of the topLevelTransaction, so that the transacted variable can identify its owning transaction.

• Two connections from the employee object to the empNo field. The first is the connection between the empNo attribute and the field itself. The second is an indirect connection through the trueElseFalse comparator

86 Using VisualAge Smalltalk ObjectExtender

between the isNotPersistent attribute of the transacted employee variable and the editable attribute. This second connection is essential. It ensures that, once an object is created, its object identifier, the empNo attribute, cannot be changed accidentally.

An alternative for the second connection is the direct connection from the isNotPersistent to enabled. The direct connection to editable produces a walkback, because the isNotPersistent attribute value of the transacted employee variable is sometimes nil, and the editable attribute of a field works only with booleans, whereas the enabled attribute can handle nil too—by interpreting nil as false.

Page 113: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

• Some helper parts doing comparisons and conversions:

• concatenator (Rb99StringConcatenator in Rb99UtilityPartsApp) concatenates the string1..6 input attributes to the signaled and read-only string attribute to build up a reasonable window title: firstNme, midInit, lastName, the class in square brackets, and the view name.

• trueElseFalse (Rb99TrueFalseNilComparator in Rb99UtilityPartsApp) converts the boolean input attribute to the signaled and read-only trueElseFalse attribute with the values true for true and false for everything else. The actual input is the isNotPersistent attribute of the transacted employee variable to set the editable attribute of the empNo key field—the object id field.

notNil (Rb99NilComparator in Rb99UtilityPartsApp) compares the object input attribute with nil and returns the signaled, read-only notNil attribute with the values true for nil and false for everything else. The actual input is self of the transacted employee variable to set the enabled attribute of the scrolledWindow—and so of the entry fields.

• An errorPrompter—added later in 5.9.2, “Add Error Information for the User” on page 99.

• A helper script, timeNowAsStringFromTimeStamp, supplying the topLevelTransaction with a name. The transaction name is displayed in the view and serves as identification when looking at the transactions in the ObjectExtender Status Tool/Browser, View->Transaction Statistics.

• All the time a (topLevelTransaction) is active. Whenever this active transaction is terminated with a commit or rollback by the user a new topLevelTransaction is created automatically through the committedOrRolledback event of the terminated transaction to enable the next transaction controlled object changes. The last active topLevelTransaction is closed automatically by closing the window (no developer connection is required).

Employee Top-Down 87

For the Rb20EmployeeView2 through Rb20EmployeeView4, the systemwide sharedTransaction and topLevelTransaction are part of the businessTransaction or enhancedBusinessTransaction.

Page 114: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 7. Connections of Rb20EmployeeView1 (Part 1 of 2)

Source (S) Feature of S Target (T) Feature of T

1 concatenator string Window title

2 containerEmployees selectedItem employee self

3 containerEmployees selectionIsValid pbMarkForDelete enabled

4 employee birthDate birthDateField object

5 employee lastName lastNameField object

6 employee midInit midInitField object

7 employee phoneNo phoneNoField object

8 employee job jobField object

9 employee comm commField object

10 employee bonus bonusField object

11 employee salary salaryField object

12 employee edLevel edLevelField object

13 employee sex sexField object

14 employee empNo empNoField object

15 employee workDept workDeptField object

16 employee firstNme firstNmeField object

17 employee hireDate hireDateField object

18 employee isPersistent tbIsPersistent selection

19 employee isNotPersistent trueElseFalse boolean

20 employee self notNil object

88 Using VisualAge Smalltalk ObjectExtender

21 employee firstNme concatenator string1

22 employee midInit concatenator string3

23 employee lastName concatenator string5

24 employee validationError errorPrompter promptFor:

25 employeeHome allInstances containerEmployees items

Note: Connections with number and source in bold are unique to Rb20EmployeeView1.

Page 115: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 8. Connections of Rb20EmployeeView1 (Part 2 of 2)

Source (S) Feature of S Target (T) Feature of T

26 notNil notNil scrolledForm enabled

27 pbCancel clicked topLevelTransaction rollback

28 pbMarkForDelete clicked employee remove

29 pbNew clicked employeeHome create

30 (pbNew,clicked --> employeeHome,create)

normalResult employee self

31 pbSave clicked topLevelTransaction commit

32 (pbSave,clicked --> topLevelTransaction,commit)

errorResult errorPrompter promptFor:

33 topLevelTransaction rootCommittedOrRolledback

sharedTransaction beginChild:

34 topLevelTransaction transactionName transactionNameField object

35 topLevelTransaction committedOrRolledback

containerEmployees items

36 topLevelTransaction self employee transaction

37 (topLevelTransaction,committedOrRolledback --> containerEmployees,items)

value employeeHome allInstances

38 (topLevelTransaction,rootCommittedOrRolledback --> sharedTransaction,beginChild:)

normalResult topLevelTransaction self

39 (topLevelTransaction,rootCommittedOrRolledback --> sharedTransaction,beginChild:)

transactionName Rb20EmployeeView1 timeNowAsStringFromTimeStamp

Employee Top-Down 89

40 trueElseFalse trueElseFalse empNoField editable

41 Window openedWidget sharedTransaction beginChild:

42 (Window,openedWidget --> sharedTransaction,beginChild:)

normalResult topLevelTransaction self

Note: Connections with number and source in bold are unique to Rb20EmployeeView1.

Page 116: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

5.8.2 Use the BusinessTransaction PartFigure 73 shows that 6 links are required to manage the basic parts sharedTransaction and topLevelTransaction (or 8 links with the transaction naming):

1. Two (or Three) on openedWidget to create the initial transaction2. Two on commitedOrRolledBack to refresh the items of the container3. Two (or Three) on commitedOrRolledBack to create the next transaction

Figure 73. View with the sharedTransaction and topLevelTransaction Parts

Replacing the sharedTransaction and the topLevelTransaction with the businessTransaction part (Figure 74) reduces the number of links from 6 to only 1:

1. One on the transaction event—triggered through the commit, the rollback, (and the request for a transaction from the transacted employee variable)—to refresh the items of the container

2.

1.

3.

90 Using VisualAge Smalltalk ObjectExtender

Figure 74. View with the businessTransaction Part

The view (available in the downloadables as Rb20EmployeeView2) with its unique connections listed in Table 8 on page 89 has almost the same behavior

1.

Page 117: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

as the Rb20EmployeeView1. Almost, because the transaction naming is not (easily) supported, and the items in the container belong to the same transaction as the edited employee. The latter you can observe, when editing, for example, the firstNme of an item. Every key stroke is also reflected in the firstNme of the item in the container. Actually, in the view with the basic transaction parts the container is filled in the context of the read-only, ever- present sharedTransaction. The context of a transaction means: That the transaction was the current one, whereas in the view with the businessTransaction part the container is filled in the context of the transaction of the businessTransaction, which is also the transaction of the transacted employee variable.

A minor addition can solve the missing transaction naming as shown in the overview Figure 75, third extract from the top, taken from the Rb20EmployeeView3 (also a downloadable), with its unique connections listed in Table 10 on page 93. The transaction of the businessTransaction can be torn off. This tornoff transaction of bT (...of businessTransaction) has (at runtime) the same behavior as the topLevelTransaction.

To keep the items of the container out of the employee editing transaction context and in the shared transaction context requires another container fill solution than the direct and indirect connection from items to allInstances. A script, for example, looking like this:

fillContainer"Fill the containerEmployees in the SharedTransaction Context"| currentTransactionSave |currentTransactionSave := Transaction current.Transaction shared resume.(self subpartNamed: ’containerEmployees’)

items: (self subpartNamed: ’employeeHome’)abtAtAttribute: #allInstances.

currentTransactionSave resume

Employee Top-Down 91

triggered from the view’s openedWidget event and from the businessTransaction’s transaction(event) would do the job. Verify the script in the VisualAge Smalltalk Composition Editor by temporarily replacing the two connections to the items with the event-to-script connections described above. The script is already defined in the downloadable.

The Transaction class supplies a convenience method if you want to force the data to be read from the database topLevelDo: aBlock. The script would then look like this (see page 94 after Table 11):

Page 118: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

92 Using VisualAge Smalltalk ObjectExtender

Figure 75. Transaction Framework Connections of Rb20 EmployeeView 1 through 4

Page 119: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 9. Connections Unique to Rb20EmployeeView2

Table 10. Connections Unique to Rb20EmployeeView3

Source (S) Feature of S Target (T) Feature of T

43 businessTransaction transaction employee transaction

44 businessTransaction transaction containerEmployees items

45 (businessTransaction,transaction --> containerEmployees,items)

value employeeHome allInstances

46 pbCancel clicked businessTransaction rollback

47 pbSave clicked businessTransaction commit

48 (pbSave,clicked --> businessTransaction,commit)

errorResult errorPrompter promptFor:

Source (S) Feature of S Target (T) Feature of T

49 businessTransaction transaction employee transaction

50 businessTransaction transaction transaction of bT self

51 businessTransaction transaction containerEmployees items

52 (businessTransaction,transaction --> containerEmployees,items)

value employeeHome allInstances

53 pbCancel clicked businessTransaction rollback

54 pbSave clicked businessTransaction commit

55 (pbSave,clicked --> businessTransaction,commit)

errorResult errorPrompter promptFor:

56 transaction of bT self transaction of bT transactionName

Employee Top-Down 93

57 transaction of bT transactionName transactionNameField object

58 (transaction of bT, self --> transaction of bT, transactionName)

value Rb20EmployeeView3 timeNowAsStringFromTimeStamp

Page 120: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 11. Connections Unique to Rb20EmployeeView4

fillContainer"Fill the containerEmployees in the TopLevelTransaction Context"Transaction topLevelDo: [

(self subpartNamed: ’containerEmployees’)items: (self subpartNamed: ’employeeHome’)

abtAtAttribute: #allInstances ]

An enhancedBusinesTransaction that offers additional features, such as an event in a sharedTransaction context and an optional transaction naming, can even further simplify the usage (Figure 75, bottom extract), with its connections listed in Table 11 on page 94.

Comment: Similar to the transacted variable, for example, an AbtTransactedViewPart could be defined. This new defined part would: inherit the behavior of the AbtViewPart and the behavior of the transaction,

Source (S) Feature of S Target (T) Feature of T

59 enhancedBusinessTransaction transaction employee transaction

60 enhancedBusinessTransaction rootCommittedOrRolledback

containerEmployees items

61 enhancedBusinessTransaction commitError errorPrompter promptFor:

62 enhancedBusinessTransaction transactionName transactionNameField object

63 (enhancedBusinessTransaction,rootCommittedOrRolledback--> containerEmployees,items)

value employeeHome allInstances

64 pbCancel clicked enhancedBusinessTransaction

rollback

65 pbSave clicked enhancedBusinessTransaction

commit

94 Using VisualAge Smalltalk ObjectExtender

know its model object in a transacted variable, and integrate user-caring support, such as the attribute isDirty (has unsaved changes), configurable and customizable confirmation pop-ups on close and on delete, and much more. This AbtTransactedViewPart would be a valuable relative to the legacy transaction or transaction program, hosted by a framework—transaction monitor—and complete and reliable in its application and use. A detailed view with all of the above functions results in a "spider-web" (Figure 129 on page 176) and makes the need for such an AbtTransactedViewPart obvious.

Back to the standard businessTransaction part:

Page 121: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

In some view scenarios, such as Rb20EmployeeViews 1 through 4, when a transaction is committed developers sometimes want the window to remain open, and other times want it to close. For example, a Save & End or OK button might commit a view’s changes and close the view, whereas a Save or Apply button might commit the changes and keep the view open. (The keyword Save is used to indicate a write to the persistent storage, whereas OK and Apply imply a commit of a nested and not topLevelTransaction.)

Whenever a transaction is committed, its stage changes from active to committed and its parent transaction is resumed. Any attempt to resume the committed (or rolled back) transaction causes a VapTransactionFailure exception. You must therefore begin a new transaction to allow the user to remain in the view at the same transaction nesting level.

The businessTransaction part caters for such a scenario, as illustrated in Figure 75 on page 92, second and third extract from top. It has a read only attribute of transaction, which it will lazily initialize to a new TopLevelTransaction. (Lazy initialization means that the transaction is created when it is first asked for if it has not been previously created and is null.) When its transaction is committed—either through the commit and rollback methods on the businessTransaction part or by the transaction being committed elsewhere—the part creates a fresh transaction. When the transaction is regenerated, the part signals the transaction event. If the transaction attribute of the businessTransaction is connected to the transaction attribute of a TransactedVariable, the TransactedVariable refreshes itself with the version of its object in the new transaction, and the user is allowed to continue working with the transacted variable's contents.

By default the businessTransaction creates a new TopLevelTransaction the first time its transaction attribute is retrieved. Rather than create this as a child of the SharedTransaction, the businessTransaction creates a private read-only transaction that it uses as the parent of its transaction. The reason for this is that when a transaction is committed its parent will be resumed. If

Employee Top-Down 95

a TopLevelTransaction is committed, the SharedTransaction will be resumed. The SharedTransaction cannot have any new objects created into it, including read-only objects that are newly read in from a data store. Having the read-only transaction as the parent, however, ensures that in the gap between the transaction being committed and refreshed the current transaction can read and refresh objects. This behavior can be toggled with the createReadOnlyParent attribute on the businessTransaction.

It is also possible to explicitly set the parent transaction that the businessTransaction should use to create its transaction as a child of. This is done through the writable attribute parentTransaction. This allows views

Page 122: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

that have to support nested transactions to be done by connecting the transaction property of one businessTransaction to the parentTransaction attribute of another. The latter transaction will be a nested child of the former, and the businessTransaction parts will ensure that whatever combination of transactions are committed or rolled back both parts have valid transactions that are nested from one another.

Because the business transaction lazily initializes its transaction when it is first asked for it, there are some circumstances where this is done before the parent transaction is set. In such cases it may be the desired behavior that the previously lazily initialized transaction (which will not be a child transaction of the new parent transaction) should be rolled back. This is the behavior by default. If this is not the desired behavior, for example, when the parent transaction is intentionally set while navigating along the hierarchy path and therefore any previously generated transactions are left active, the boolean attribute rollbackTransactionWhenParentChanges should be toggled.

5.9 Run Sample with User Interface

We recommend that you now use the newly created GUI to create, edit, and delete employee records.You are soon likely to notice that the application has some quirks:

• The sex field accepts any single-character string instead of only M or F. When more than one character is entered in this field, the update transaction aborts (look at the System Transcript window to see this). The abort is signaled from the DB2 database itself, with the error message that the value is too long. However, the user gets no other obvious indication that anything has gone wrong.

• The GUI is not very user supportive: there is no warning about unsaved changes when leaving or closing the window, new items do not show up in the list until the save(commit) is performed, items marked for delete are

96 Using VisualAge Smalltalk ObjectExtender

not marked in the list, there is no indication about pending changes, and no confirm dialog is given for the delete command.

• The application reads all instances from the persistent storage. That is acceptable only for a sample.

• On a rollback, there is no way to recover the pending changes. They are just lost. This is not so bad if you perform a commit after every new, changed or deleted employee, but when you do multiple changes—and the GUI implementation invites you to do that—it becomes worse.

• And last, but not least, the application has no concurrence support built in.

Page 123: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

5.9.1 Add Error Handling and Error EventsWhat is missing from the application at the moment is error handling. It is always a point for debate as to whether the error-handling code should be in the GUI or in the object itself. While recognizing that there are valid arguments for each case, we have chosen to take a firm object-oriented line in writing this sample. We chose to implement the error-handling code primarily in the object so that we could illustrate the implementing error handling.

To implement error handling for the sex field, we need to add code to the Rb20Employee object. Using the VisualAge Organizer, open the Rb20Employee object for editing. Using the Public Interface Editor, create a new event, validationError, as shown in Figure 76. This event passes one parameter, an AbtError object, and allows us to signal some details about the error.

Employee Top-Down 97

Figure 76. Public Interface Editor with the validationError Event

Page 124: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The next stage is to add some validation code. Using the script editor, open the code for the sex: method. The generated code looks like this:

sex: aString"Set the value of the attribute sex in the current transaction.

| newValue |newValue := aString.

"Begin user code {pre-Set}""End user code"

self bom markModified.^self bom versionDataForUpdate primSex: newValue

Note that there is a section specifically provided for user code. In this section, write the following code snippet:

newValue notNil ifTrue: [ "because sex is not required"newValue := newValue asString asUppercase.#(’M’ ’F’) includes newValue ifFalse: [ | err |

err := AbtError newerrorText: ’Sex has to be M or F’;locus: ’in validation’.

self signalEvent: #validationError with: err.^err ] ].

This code snippet converts the input to an upper-case string (only M or F, not m or f). It then checks that it is either M or F. If not, it creates an AbtError object with an error message and signals the validationError message. If the sex: setter is used in a script, the error err is returned too and can be checked like a return code object:

(employee sex:aVariable) isAbtError ifTrue: [...

Having inserted and saved this code chunk, you can try running the sample

98 Using VisualAge Smalltalk ObjectExtender

again. This time, looking at the System Transcript, you will see that lower- case entries in the sex field are converted to upper case and that erroneous entries are ignored. However, the application still has a small problem: The user has no idea that he or she has made a mistake. The user should be told this in an error message in either the message area of the application window or a separate error dialog window.

Page 125: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

5.9.2 Add Error Information for the UserAdd a MessagePrompter object named errorPrompter in the Composition Editor, with the settings shown in Figure 77.

Figure 77. errorPrompter Properties

Connect the validationError event of the Employee object to the promptFor: action of the errorPrompter object.

Running the application now produces a dialog box like that shown in Figure 78 whenever an invalid entry is made in the sex field. Note that you can leave the field, and the view still displays the erroneous input, although the object stays clean. Of course, with only two choices for this field, a better GUI design would use a combo box so that it would be impossible for the user to make an invalid entry.

Employee Top-Down 99

Figure 78. Validation Error Dialog

The approach we have used is very general. Validating other fields requires only that we edit the relevant method code on the Rb20Employee object to generate a validationError event with appropriate error text when an attribute fails validation.

Page 126: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Note: The solution proposed above cannot be the final solution when: the transacted variable is cleared, it triggers the validationError event with a nil argument, opening an empty error message window.

5.9.3 Add Database Error HandlingAs we have developed this sample, database errors have been displayed in the System Transcript as they occur. We should therefore add one more error handling feature to alert the user (or perhaps the developer during testing) when something unexpected happens with the database.

So, connect the errorResult event of the connection between the Save button and the topLevelTransaction to the promptFor action of the errorPrompter. When you run the sample again, try an erroneous operation (for example, try four characters for the work department). As a result, you are presented with the full SQL error message (Figure 79).

Figure 79. SQL Error Passed by the topLevelTransaction

Of course, we could have caught this error earlier, before it hit the database. The user interface can, in a matter of seconds, be modified to limit the length of this field to no more than three characters. We could also have implemented validation in the Employee object’s workDept: method.

Note: If you get an empty error(message)Prompter, have an errorPrompter for

100 Using VisualAge Smalltalk ObjectExtender

each of the error events: errorResult from the commit action of the transaction and validationError from the employee transacted variable. (The employee transacted variable sends on nil not only for the self event, which is correct, but also for dedicated events, such as the validationError, because they may be deferred or delayed events. Adding a Rb99NilComparator between the employee transacted variable and the errorPrompter, feeding its object attribute with the validationError event, and catching its notNilObject event for the promptFor: action of the errorPrompter solve the problem too.)

Page 127: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

5.10 Stand-alone Application (GUI with Image Schema)

Figure 80 shows the GUI Rb20EmployeeViewLIS, that runs with the local image schema and data store as a stand-alone application (see 1.5.3, “Application Data” on page 16). ObjectExtender’s service class for the local image data store—ImageServiceObject—has the #save, #load, and #reset protocol to manipulate the local image data store as a whole.

Employee Top-Down 101

Figure 80. Local Image Data Store Dedicated Rb20EmployeeView

The view extends Rb20EmployeeView3 in Figure 75 on page 92 with buttons and scripts to control the local image data store (LIS:) and the list:

• Activate data store (usually executed in ObjectExtender status tool) • Save local image data store in a file. A file dialog asks for the file name.

Page 128: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

• Load local image data store from a file. A file dialog asks for the file name.

• Reset—clear— the local image data store. All data is removed. • Refresh List—each load, reset, transaction start, and direct user request

updates the list (#fillContainer) with employeeHome>>#allInstances.

5.11 Summary and Conclusions

We have shown and discussed the first implementation of the employee sample, restricted to the Employee object.We:

• Defined our model class, Rb20Employee

• Generated the supporting model code

• Created a corresponding schema automatically for a local image data store with an image database. Remember: only the data store and the service classes were generated, neither a schema nor map was generated

• Verified the image database

• Exercised the image database without a GUI (headless)

• Created a new schema to work with the DB2 database

• Created the physical database automatically using the new schema

• Established a new set of mappings between our model class, Rb20Employee, and our schema, once the schema was generated

• Generated the service classes and supporting code required to access the physical database, using the generation facilities of the Map Browser.

• Exercised our access to the DB2 database, headless.

• While exercising both the image database and the DB2 database, used some of the status monitoring tools and had a brief look at the way the persistence framework operated.

102 Using VisualAge Smalltalk ObjectExtender

• Built a small GUI application to access the Employee table in a more friendly manner. We developed the application quickly, following the guidelines in the ObjectExtender User’s Guide and Reference.

• Used in the GUI the basic transaction parts sharedTransaction and topLevelTransation and experienced the simplification with the businessTransaction part.

• Controlled which transaction is the current transaction to set up the "right" context for the various functions in the GUI

• Added limited validation error handling to the application and learned how to add validation code to the object

Page 129: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

• Added database error handling.

In our opinion, the main lessons learned from this sample are:

• VisualAge ObjectExtender provides a very powerful framework for developing transaction processing applications in a short time.

• The GUI reduces the need for application developers to get involved with the internal details of the Smalltalk system, although it does not eliminate the need entirely.

• Design for error handling is essential. The designer needs to think through whether errors should be handled at the GUI level, or in the object itself or merely trapped when they eventually occur.

• Object identifiers (normally the object’s primary key) are sacrosanct. Once an object has been created, do not attempt to change its object identifier.

• There are two ways of implementing transactions: with the basic parts, such as the shared and top level transaction, or with the dedicated business transaction. The business transaction offers simplicity—especially in visual programming—but is limited in general purpose and option.

Employee Top-Down 103

Page 130: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

104 Using VisualAge Smalltalk ObjectExtender

Page 131: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 6. Employee Bottom-Up

The Employee Bottom-Up sample looks at just one table, the Employee table of the DB2 sample database (Figure 81) and follows the backward or bottom-up development path (see 2.2, “Backward or Bottom-Up: Start with the Database” on page 20 and Figure 11 on page 21). The sample uses the name prefix Rb21, except where parts from the previous sample are reused.

Figure 81. DB2 Sample Database: Employee Table with Columns

© Copyright IBM Corp. 1999 105

To exercise this sample, you should have the DB2 sample database created, and the DB2 database manager must be started. You can start the DB2 database manager in a system command window with db2start and create the DB2 sample database with db2sampl. The sample database installation uses your userid as the (high-level) qualifier (see also the Note on page 67). If the DB2 sample database is not created or not available, you can use the database and table you created in 5.3.5, “Generate the DDL and the Database Tables” on page 66.

Page 132: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

6.1 Import Schema from Relational Database (Metadata)

As you are working with an existing database, you have to generate the schema from the database. The first stage is to use the Schema Browser to create the necessary schema from the database.

From past experience, you know that you need to select suitable names for everything. So, when asked, name the schema Rb21Employee, and save the schema in a new application, Rb21EmployeeSchemaApp. Accept the default storage class name of Rb21EmployeeSchema when you save the schema for the first time.

Import the schema from the database by selecting Schemas-> Import / Export->Import Schema from Database ... from the menu bar of the Schema Browser (Figure 82).

Figure 82. Schema Browser: Import / Export Menu

Establish connection with the database in the same way as shown in Figure

106 Using VisualAge Smalltalk ObjectExtender

54 on page 67—but with SAMPLE as Data source. Then select the table you want (Figure 83 on page 107).

Page 133: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 83. Select Tables Dialog: All Tables of the DB2 Sample Database

After saving the newly generated schema (Figure 84), the Schema Browser shows that the new table has been created with the logical name Employee (Figure 85 on page 108).

Employee Bottom-Up 107

Figure 84. Imported Database Schema Rb21Employee

Page 134: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 85. Imported Table: Still Logical Employee and without Primary Key

To avoid confusion with other applications that have been developed, change the logical name of the table by adding the Rb21 prefix, using the Table Editor (Figure 50 on page 63). Note that the Table Editor calls the name just Name.

Remember, two greater-than signs (">>") to the left of the column name indicate a primary key column (Figure 49 on page 62). The primary key

108 Using VisualAge Smalltalk ObjectExtender

columns are also listed in the Table Editor (Figure 50 on page 63). If ObjectExtender cannot detect the primary key columns and add the primary key definition (Figure 85 on page 108) because the captured table has no primary key definition in the database, you have to define the primary key manually, using the Table Editor. The EMPNO column has to be the primary key of the EMPLOYEE table.

Page 135: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

6.2 Generate Model Definition and Mapping (Metadata)

In Chapter 5, “Employee Top-Down” on page 47, you developed a model for the Employee object. You can reuse this object to develop your model. However, you actually generate the model from the schema you have just created, selecting Schemas->Generate Model from Schema from the menu bar of the Schema Browser (Figure 82 on page 106).

If you forgot to define the primary key columns in 6.1, “Import Schema from Relational Database (Metadata)” on page 106, you receive the error message shown in Figure 86.

Figure 86. Error message for undefined Primary Key Columns after Import

Now open the Model Browser and find the new model that has been generated (Figure 87 on page 110).

The model has the same name as the logical name of the schema, namely, Rb21Employee, and its one and only class has the same name as the logical name of the table, namely, Rb21employee (note the lower-case emp...). If the model does not have the name RB21Rmployee, you might have forgotten to change the logical name of the schema originally derived from the physical name at import time. If you forgot, delete the model (and map), do the renaming as requested in 6.1, “Import Schema from Relational Database (Metadata)” on page 106, and generate the model once again.

Employee Bottom-Up 109

Look at the attribute names in the textual summary created for your new Rb21Employee model class, as shown in Figure 87. Note that the attribute names have been taken directly from the database column names. It is not possible to change these names. If a project requires more meaningful names, the attributes must be entered manually rather than by using the automatic generation feature, and consequently the mappings have to be entered manually.

Page 136: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 87. Generated Model Rb21Employee

As you save the model, you are asked for the application name and the class name. In this case, use Rb21EmployeeModelApp and Rb21EmployeeModel, respectively.

ObjectExtender has also generated the mappings between the model and the schema for you.

110 Using VisualAge Smalltalk ObjectExtender

Open the Map Browser and look at its contents. ObjectExtender has created a data store map named Rb21EmployeeRb21employee, as shown in the extract from the Map Browser in Figure 88. If you do not like this name, delete the map and enter the details manually.

Page 137: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 88. Generated Map Rb21EmployeeRb21employee

6.3 Generate Code to Support Model and Services

Now you have to generate the code to support the sample. This is a two-stage process. Follow these steps:

1. In the Model Browser, check that the model code generation options are as shown in Figure 89.

Employee Bottom-Up 111

Page 138: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 89. Model Generation Options for the Rb21Employee Model

2. Use the Model Browser to generate the model code.

3. In the Map Browser, check that the service code generation options are as shown in Figure 90.

112 Using VisualAge Smalltalk ObjectExtender

Figure 90. Service Code Generation Options for the Rb21Employee Model

4. Note that ObjectExtender has automatically generated a name for the service application. If no database connection is shown, you can specify a connection by clicking on the Change....button and completing the database connection dialog as shown in Figure 91.

Page 139: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 91. Database Connection Information for the Rb21Employee Model

5. Use the Map Browser to generate the services.

6.4 Run Sample Headless with Scripts

We have now completed the basic application, without any GUI. We need to test it briefly, as explained in 5.6, “Run Sample Headless with Scripts” on page 72:

1. Use the Status Browser to activate the data store Rb21EmployeeRb21employeeDataStore or a suitable window such as a Workspace window in which you execute this Smalltalk expression:

Rb21EmployeRb21employeeDataStore singleton activate

2. Execute the following Smalltalk expression in a suitable window such as a Workspace window to query the database for all employees:

Employee Bottom-Up 113

Rb21employeeHome singleton allInstances inspect

The result of this expression is a window similar to that shown in Figure 92.

Page 140: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 92. Result of Inspecting Rb21employeeHome singleton allInstances

If you had the Detailed Trace on, the System Transcript would show a trace like that shown (partially) in Figure 93 on page 114.

114 Using VisualAge Smalltalk ObjectExtender

Figure 93. Extended Trace of Rb21employeeHome allInstances

Page 141: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The trace demonstrates that we have successfully established a connnection to the database and can read the rows from the database. The next stage is to add a GUI.

Before you go to work on a GUI, check that the schema, model, and map of the Rb21 sample are saved. Furthermore, you can version and release the generated model code classes, services code classes, and applications.

6.5 Adding the User Interface

To add a GUI interface you could repeat the steps in 5.8, “Create Views with Transactions” on page 83, using the new class names for the Employee and EmployeeHome objects, namely, Rb21employee and Rb21employeeHome.

But for this sample, we go one step further. We show you how to develop a GUI with a list with all instances for selection, (Rb21EmployeeListView), and windows (Rb21EmployeeDetailView) for single instances for CRUD, create and insert, read, update, and delete (Figure 94). The windows for the single instances are opened in the List view by clicking on the New button for a create and insert and by double-clicking on a list item for an update or a delete. The Rb21views are classes in the Rb21EmployeeViewApp.

List

Alex

Bob

Chris

Alex

Save Cancel

Firstname

Xxxxxx

Bob

Save Cancel

Firstname

Xxxxxx

New

Firstname

double-click

Bob

Bobby

Employee Bottom-Up 115

Figure 94. List Window with Multiple Single Windows

After you complete this section and 6.6, “Run and Monitor the List and Detail View GUI” on page 122, there will still be room for improvement in designing and implementing water-and air-tight GUIs and transactions with VisualAge Smalltalk Enterprise and ObjectExtender.

New Refresh

clickSave Cancel

Xxxxxx

Page 142: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

6.5.1 Create a List ViewFigure 95 shows the layout of Rb21EmployeeListView in the Composition Editor. Table 12 on page 118 lists all the connections.

Note: When you copy containerEmployees from the Rb21View, you must change a few things, because creating a model from a database and creating a database from a model do not exactly work the same way. First, you have to change the containerDetails (column) attribute names to lower case, for example, empNo to empno. Second, you must change the containerDetails converter of the midinit (middle initial) to Character. Double-click on the view item to open the settings dialog of the part and perform the adjustment.

5.

2.

4.1.

3.

6.

116 Using VisualAge Smalltalk ObjectExtender

Figure 95. Rb21EmployeeListView

The key features of the Rb21EmployeeListView are:

• EmployeeHomeT, which is transacted by the sharedTransaction ensures, that allInstances are taken from the read-only transaction context (sharedTransaction).

Page 143: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

• The "standard connection" between employeeHomeT allInstances and containerEmployees items is missing, because it would fire twice on startup, and the database would have to deliver all table entries twice.

• The initial filling of the table—using the openedWidget event—is a hook on the refresh button click action. The refresh button clicked event gets the collection from the home and sets the containerEmployees items.

• The connection firing sequences for the new the update and the actions delete are crucial to the correct working of the sample. If your sample does not work and your symptoms are, for example, nil values, you should check and change the connection orders on the parts by selecting Reorder Connections From from their pop-up menu:

• Firing sequence for the new initiated by a click on the New Employee push button pbNew:

1. The initiating clicked event of the pbNew push button fires a new to the EmployeeDetailView factory.

2. The new on the factory grabs the sharedTransaction for the (promoted) parentTransaction of the businessTransaction of the just created detailView instance.

3. The torn-off employeeDetailView variable is set to the just created detailView instance.The normalResult event of the new sent to the EmployeeDetailView factory (in 2.):

4. Grabs a new employee instance from the transacted employeeHomeT by firing a create to the employeeHomeT

5. Sets the (promoted) tempEmployee (standard) variable of the torn-off employeeDetailView instance

6. Opens the employeeDetailView by firing the openWidget message to the employeeDetailView instance

• Firing sequence for update/delete initiated by a double-click on an element in containerEmployees: The firing sequence is the same as for the new above, but with three small changes in the participating parts,

Employee Bottom-Up 117

the events, and the actions:

• The initiating defaultActionRequested event of the containerEmployees sets internally the selectedItem and fires externally.

• The new to the EmployeeDetailView factory (in 1.) is fired by the initiating defaultActionRequested event of containerEmployees, which first and internally sets its selectedItem to the double-clicked item.

• The argument to set the (promoted) tempEmployee (standard) variable of the employeeDetailView (in 4.) is picked up from the just internally set selectedItem of containerEmployees.

Page 144: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 12. Connections of Rb21EmployeeListView

Source (S) Feature of S Target (T) Feature of T

1 ( (containerEmployees,defaultActionRequested --> EmployeeDetailView,new),normalResult --> employeeDetailView,employeeTmp)

value containerEmployees

selectedItem

2 ( (pbNew,clicked --> EmployeeDetailView,new),normalResult --> employeeDetailView,employeeTmp)

value employeeHome

create

3 containerEmployees defaultActionRequested

EmployeeDetailView

new

4 (containerEmployees,defaultActionRequested --> EmployeeDetailView,new)

normalResult employeeDetailView

employeeTmp

5 (containerEmployees,defaultActionRequested --> EmployeeDetailView,new)

normalResult employeeDetailView

openWidget

6 EmployeeDetailView instance employeeDetailView

self

7 employeeHome self employeeHomeT

self

8 pbNew clicked EmployeeDetailView

new

9 (pbNew,clicked --> EmployeeDetailView,new) normalResult employeeDetailView

employeeTmp

10 (pbNew,clicked --> EmployeeDetailView,new) normalResult employeeDetailView

openWidget

11 pbRefresh clicked containerEmployees

items

12 (pbRefresh,clicked --> containerEmployees,items)

value employeeHomeT

allInstances

118 Using VisualAge Smalltalk ObjectExtender

13 sharedTransaction self employeeHomeT

transaction

14 sharedTransaction self EmployeeDetailView

businessTransactionParentTransaction

15 Window openedWidget pbRefresh click

Page 145: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

6.5.2 Create a Detail ViewFigure 96 shows the layout of Rb21EmployeeDetailView in the Composition Editor. Table 13 on page 121 lists all the connections.

Figure 96. Rb21EmployeeDetailView

The key features of the Rb21EmployeeDetailView are:

• The businessTransaction is used to simplify the construction.

• Not crucial to this sample, but worth noting:

Employee Bottom-Up 119

The businessTransaction part has its parentTransaction feature promoted as businessTransactionParentTransaction. The promotion of the parentTransaction enables the view to be in a nested transaction level deeper than the topLevelTransaction-sharedTransaction nesting.

However, in this sample, the transaction of the businessTransaction is in all situations a topLevelTransaction and writes to the persistent storage when committing. If no sharedTransaction is supplied as parent transaction, the businessTransaction creates a topLevelTransaction as its transaction on its own to manage the situation. You can verify this by

Page 146: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

removing the connection from the sharedTransaction to the EmployeeDetailView factory in the Rb21EmployeeListView. Everything runs just fine as before (Figure 95 on page 116).

• The (standard) tempEmployee variable is used to decouple the "sending" from the "receiving" transaction.

Transacted variables do a transaction switching—that is what they are built for. But the direct connection between one transacted variable in one transaction context and another transacted variable in another transaction context does not work properly. The combination of the plain vanilla (standard) temp variable and the delayed event for picking up the value in the variables is a perfect construction for decoupling two transacted variables of different transaction contexts. The event for picking up the variable value and storing it in the new transaction variable is the openedWidget event of the Window of the EmployeeDetailView and is totally asynchronous to the normalResult return event of the new sent to the EmployeeDetailView factory to create the employeeDetailView instance.

• The only enhancement beyond what you already know from 5.8, “Create Views with Transactions” on page 83 is the deleteConfirmer—shown in action in Figure 97 on page 122. There is no mystery about the connections the deleteConfirmer uses to interface with the actual view and the transacted variable.

A successful commit closes the window, and an intended and an unintended rollback and "business as usual" for the businessTransaction: The businessTransaction just creates "lazily" a correct, new transaction with which to resume.

120 Using VisualAge Smalltalk ObjectExtender

Page 147: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 13. Connections of Rb21EmployeeDetailView

Source (S) Feature of S Target (T) Feature of T

1 businessTransaction transaction employee transaction

2 concatenator string Window title

34

deleteConfirmerdeleteConfirmer

okYesRetryokYesRetry

employeebusinessTransaction

removecommit

5 (deleteConfirmer,okYesRetry --> businessTransaction,commit)

normalResult Window closeWidget

6789

10

employee firstnmeempnomidinitedlevellastname

firstNmeFieldempNoFieldmidInitFieldedLevelFieldlastNameField

object

11 employee isNotPersistent trueElseFalse boolean

121314

employee firstnmemidinitlastname

concatenator string1string3string5

15 employee isPersistent pbDelete enabled

161718192021222324

employee phonenojobworkdepthiredatesexbirthdatebonuscommsalary

phoneNoFieldjobFieldworkDeptFieldhireDateFieldsexFieldbirthDateFieldbonusFieldcommFieldsalaryField

object

25 pbCancel clicked businessTransaction rollback

Employee Bottom-Up 121

26 pbDelete clicked deleteConfirmer prompt

27 pbSave clicked businessTransaction commit

28 (pbSave,clicked --> businessTransaction,commit)

normalResult Window closeWidget

29 trueElseFalse trueElseFalse empNoField editable

30 Window openedWidget employee self

31 (Window,openedWidget --> employee,self)

value employeeTmp self

Page 148: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

6.6 Run and Monitor the List and Detail View GUI

The GUI developed in the previous sections "works as designed" (Figure 97).

Every click on the NewEmployee button and every double-click on an employee in the EmployeeListView opens an independent EmployeeDetailView. Each double-click on an employee in the list opens a new detail view, even if you double-click on the same employee again and again. You can close the list view; the detail views stay open.

122 Using VisualAge Smalltalk ObjectExtender

Figure 97. List and Detail View with the Deletion Confirmer in Action

The Delete button in the EmployeeDetailView is disabled for new employees. Clicking on the Delete button for an already persistent employee shows the Confirm Deletion dialog.

Saving or deleting an employee closes the EmployeeDetailView, whereas a reset creates a rollback only, and the view stays open. When you close the window a rollback automatically occurs.

Page 149: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The application does not prevent the user from overwriting rows in the database tables, and the user can throw away changes without a confirmation. For the Reset such a function would be implemented in the same way as the DeletionConfirmer. For the change detection, more work must be done, because neither the transaction, the object, nor the transacted variable has a public interface to have access to the isChanged information.

In Figure 98 employee 000030 SALLY A KWAN was opened four times in a detailed view from the List view.

Figure 98. One Plus Four Object Versions of Employee 000030.

Employee Bottom-Up 123

Use ObjectExtender’s Status Tool/Browser and (inspector enablement) to play with transactions and object versions. For every EmployeeDetailView you open, a new child transaction of the sharedTransaction—a topLevelTransaction—is created. Verify this by selecting View->Transaction Statistics between subsequent view opens without closings (Figure 99).

Page 150: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 99. View and Inspect Transactions and Transaction Statistics

For every employee object you touch in the EmployeeDetailView, a new version of that touched object is created. As many open views with changes you have of one object, as many versions you have of the object—plus one: the origin. Inspecting allInstances of the class shows them (Figure 100).

124 Using VisualAge Smalltalk ObjectExtender

Page 151: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 100. Fife (1+4) Instances of Employee 000030 in allInstances

Employee Bottom-Up 125

Page 152: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

126 Using VisualAge Smalltalk ObjectExtender

Page 153: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 7. Employee and Department Top-Down

The Employee and Department Top-Down sample looks at two classes—the Employee and Department class—and the associations between them (Figure 101) and follows the forward or top-down development path (see 2.1, “Forward or Top-Down: Start with the Object Model” on page 19 and Figure 11 on page 21). The sample uses the name prefix Rb30.

Figure 101. Class Diagram for Employee and Department Sample

No attempt is made to reuse classes or parts developed earlier—except the non-sample-related helper parts—because each sample demonstrates

< worksIn

isManagedBy >

isAdministeredBy >

Department Employee

* 1

*

1

0..1 0..1

employeeNumbernamephoneNumberworkDepartment...

departmentNumbernamemanageradminDepartment...

managedDepartment

manager

administrative

departments

workDepartment

employees

has >

< administers

< manages

Department

© Copyright IBM Corp. 1999 127

something different, and we want each sample to stand alone, something that would be difficult to guarantee if we reused classes.

7.1 Define Model (Metadata)

The starting point for defining the model is the Model Browser. The model is defined in the same way as in 5.1, “Define the Model (Metadata)” on page 47, except for a few new things, of course. New to this sample are the associations. Information that was just a simple (data) attribute in the previous samples—for example, the workDepartment of the employee—is now

Page 154: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

part of an association between the Employee and the Department and is treated differently in an extra step (see 7.1.4, “Define Associations” on page 129).

7.1.1 Create New ModelCreate the model, name it Rb30EmpDept, and save it in Rb30EmpDeptModelApp and storage class Rb30EmpDeptModel. An alternative project name would be Rb30Company..., but that name would imply that the company object would also be modeled.

7.1.2 Define ClassesAdd the Rb30Employee and Rb30Department classes to the model.

7.1.3 Define AttributesAdd the attributes for the two classes you have created. The attributes for Rb30Employee are the same as those listed in Table 3 on page 51. They are repeated here, in Table 14, for ease of reference.

Table 14. Attributes for the Rb30Employee Class

Attribute Name Attribute Type Required (Comment)

1 birthDate Date No

2 bonus ScaledDecimal No

3 comm ScaledDecimal No

4 edLevel Integer Yes

5 empNo String Yes (Object ID)

6 firstNme String Yes

7 hireDate Date No

128 Using VisualAge Smalltalk ObjectExtender

8 job String No

9 lastName String Yes

10 midInit String Yes

11 phoneNo String No

12 salary ScaledDecimal No

13 sex String No

14 workDepartment Rb30Department No (Association)

Page 155: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 15. Attributes for the Rb30Department Class

Table 14 and Table 15 also show which attributes (one in each table) are used for associations. Now add all attributes except the associations using the Attribute Editor.

7.1.4 Define AssociationsOnce you have entered the class attributes and set the object identities for each class, use the Association Editor of the Model Browser to set up the associations between the two classes (Figure 102 on page 130).

It is important to select the names for the associations carefully, to avoid later confusion. As associations are listed separately from classes in the Model Browser, and later on generated service classes and methods will include the association name in their name, expand the name beyond that shown in the class diagram, so that it is obvious which association is meant. The Association Editor suggests using the two roles separated by an underscore character (_) or the phrase "to" to build the association name (in Figure 102 the underscore is shown as dash), example, for the employees (Role1) and work department (Role2) as shown in Figure 103 on page 130, left

Attribute Name Attribute Type Required/Comment

1 administrativeDepartment *Rb30Department Yes (Association)

2 administrativeDepartment Rb30Department Yes (Association)

3 deptName String Yes

4 deptNo String Yes (Object ID)

5 employees *Rb30Employees No (Association)

6 location String No

7 manager Rb30Employee No (Association)

Employee and Department Top-Down 129

side:

employees_workDepartment

A good alternative is to use both classes with the association name as infix, for example, as shown in Figure 103, right side:

department-has_employees

Note the reversed sequence of the class names in the association name, while the same sequence of role names employees - workDepartment is maintained.

Page 156: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 102. Association Editor View Opens with Name Templates

Class2

of Class1 in Class2

Class1

of Class2 in Class1

130 Using VisualAge Smalltalk ObjectExtender

Figure 103. has Association Naming Relationships

Note: The underscore character or the "to" phrase in the association name is not necessarily required, but it helps ObjectExtender create reasonably shortened physical names for the constraints to insert into the database. ObjectExtender identifies the name components of an association name by the underscore and truncates each component proportionally until the whole name fits the length limit of the database. Remember the

Page 157: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

VapDatabasePhysicalRules class to set the #maximumLength:, build database-conforming physical names, and customize name creation by subclassing. We extended the VapDatabasePhysicalRules (and some other related) classes in VapDatabasePhysicalRulesXApp to facilitate use and customizing—we even allowed dashes for separators as the Association Editor implies. You will use the basic and extended version in 7.3.2, “Generate Conforming Physical Names” on page 140. The application is part of the Appendix C, “Downloadables, ConfigMaps, Applications” on page 355.

You must also think carefully about the other parts of the Association Editor dialog. The association is between two classes, for example, Rb30Employee and the Rb30Department.

For the Roles of... you can say:

• In the Rb30Department class, the role of the Rb30Employee is (has) employees.

• In the Rb30Employee class, the Rb30Department is the workDepartment.

For the Navigables you can say:

• Yes for the Rb30Department class, because you want to ask a department for its (has) employees.

• Yes for the Rb30Employee class, because you want to ask an employee for his or her work department.

For the Manys you can say:

• Yes for the Rb30Department class, because a department can have (has) many employees.

• No for the Rb30Employee class, because an employee can work in only one department.

Employee and Department Top-Down 131

For the Requireds you can say:

• No for the Rb30Department class, because a department can exist without (has no) employees.

• No for the Rb30Employee class, because an employee can exist without working in a department.

The No in the Manys and the Nos for the Requireds are biased because of the DB2 sample database. The No in the Many for the department is given through the fact of the one-to-many relation—only one department can have one and the same employee at a time or an employee can work in only one

Page 158: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

department (full-time in one department). The No for the Requireds is given through the fact of the null-able workdept column in the employee table.

The direction of the one-to-many associations is for technically not relevant ObjectExtender. The namings for the same sample relation with reversed direction would then be as in Figure 104.

Figure 104. WorksIn Association Naming Relationships

For the Employee and Department sample we suggest using the Role1-Role2 naming schema, and—for the actual sample association— the direction as shown in Figure 103 on page 130, even though the has association is not really a has-association (department "has" employees). For a real has-association, such as an order has orderItems, the direction as shown in Figure 103 on page 130 would be the (only) natural choice.

There are three associations to enter, supporting the three associations in the Employee and Department sample as shown in Figure 101 on page 127.

132 Using VisualAge Smalltalk ObjectExtender

The first association—has or worksIn—was just used as an actual sample to introduce and explain the Association Editor in the paragraphs above. Now enter the association with the values shown in Figure 103 on page 130, on the left.

The second association is the manages or isManagedBy association with the roles manager and managedDepartment (Figure 105). In this association, we want to be able to navigate from department to manager and from manager to department, so both Navigable check boxes are checked. Departments only ever have one manager, and an employee can only ever manage one department (while this may not be true in the real world, it is the case for our

Page 159: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

sample), so neither Many check box is checked. Finally, not all departments have a manager and not all employees are department managers, so neither Required check box is checked.

The manages and isManagedBy association is a one-to-one association. The direction of the one-to-one associations is for relevant ObjectExtender when generating the schema for a relational database and placing the foreign key. The foreign key is placed in the table that will be mapped from Class1, or in other words, in the table that corresponds with the class playing Role1. Therefore, the settings to the right in Figure 105 are correct.

Figure 105. One-to-One Association: Manages or isManagedBy

The third and last association is the administers or isAdministeredBy association with the roles departments and administrativeDepartment (Figure 106). In this association, we want to be able to navigate from one level in the department hierarchy to the next lower or upper level, so both Navigable check boxes are checked. Not every department administers inferior departments, but every department is ministered by a superior

Employee and Department Top-Down 133

department. So, for the Role1/Class2 side (departments), the Many check box is checked and the Required check box is unchecked, and for the Role2/Class1 side (managedDepartment), the Many check box is unchecked and the Required check box is checked. This results in a special situation for the department, which is on the top of the hierarchy of this typical— tree with root, nodes, and leaves—construct: The root department administers itself, and is recognized as the root department by this very fact.

The resulting Model Browser display now looks like that shown in Figure 107.

Page 160: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 106. Administers Association

Note that the Rb30Department has only three (value) attributes in the textual summary, but four additional (relation) attributes in the Class Attributes list that are marked with an r in parentheses in front of the name. These four association attributes are derived from the three associations in the Class Associations and have the names of the roles (role in).

Note further that each Navigable end of an association becomes a relational attribute.

134 Using VisualAge Smalltalk ObjectExtender

Figure 107. Model Browser: Department Class

Page 161: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

7.2 Generate Code for the Model Classes

Before generating the code for the real model classes (rather than the metadata defining the classes), in the Model Browser select Models->Model Code Generation Options to check that the generation options are correct. They should be as shown in Figure 108. If you do not want to generate all code into the same application, continue with 7.2.1, “Generate Model Code into Different Applications” on page 135.

Figure 108. Rb30 Sample Code Generation Options

Now generate the classes and code to support the model, using the Generate command in the Model Browser, and continue with 7.2.2, “Review Generated Model Class Code” on page 136.

7.2.1 Generate Model Code into Different ApplicationsIf you want to generate the model code into different applications follow these generic steps to set the model code generation options and to generate the model code:

Employee and Department Top-Down 135

1. Generate the code for the associations.

For each class or class cluster tupel with associations, choose an application name, set the generation options accordingly, and generate the code for the associations between the tupel items.

For the Employee and Department sample, choose the Rb30DeptYEmpApp application for the generation of the employees-workDepartment and manager-managedDepartment association code, and the Rb30DeptYDeptApp application for the departments-administrativeDepartment association code. (The Y

Page 162: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

separates the tupel names and is related to a naming concept, where extensions are named Item1XItem2App and called Item1 eXtensions requested by Item2.)

2. Generate the code for the classes twice.

For each class or class cluster, choose an application name, set the generation options accordingly, and generate the code for the class or class cluster.

For the Employee and Department sample, choose the Rb30DeptApp application for the generation of the Rb30Department class and the Rb30EmployeeApp for the Rb30Employee class.

Some partial generations will complain about undefined globals, and some will ask to replace an already defined global by a class. The compiler can not compile generated sources with undefined globals. The complaining generation has to be rerun.

3. Adjust the prerequisites.

Some partial generation will also complain through the repository in the System Transcript about undeclared prerequisites with

Warning: 49 ClassA>>#methodB should not reference CApp::ClassD.

Adjust the prerequisites of the applications complaining about undeclared prerequisites as best you can. Situations with circular references among parcels are never complaint free.

7.2.2 Review Generated Model Class CodeTake a look at the generated classes in Rb30EmpDeptApp in the VisualAge Organizer (Figure 109). In addition to the model, home, and key kind of class, which are already known from the Employee sample (Figure 46 on page 56), six association classes—one for each (navigable) role in the model— have been generated.

136 Using VisualAge Smalltalk ObjectExtender

Take a look at the methods of the Rb30Department class related to the associations (Figure 110 on page 138).

ObjectExtender generated the getter—but no setters—for the Many associations departments and employees and for each an add... and remove... action for your convenience. If you are not comfortable with the names that ObjectExtender created—because the add and remove are of a single item,— you can change the names for the method and the argument, for example, to addDepartment: aDepartment. Using these add... and remove... methods unburdens you from setting the foreign key in the many-elements in the one-to-many relationships.

Page 163: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 109. Model Classes for the Employee and Department Sample

ObjectExtender may generate isForward := true twice in the one-to-one relationship initialization methods, for example, in the one-to-one Rb30DepartmentToManagerRelationship class and in the one-to-one

Employee and Department Top-Down 137

Rb30EmployeeToManagedDepartmentRelationship class. Make sure that the latter class sets its isForward to false. The class with the foreign key is the forward relationship, the other class is the backward relationship.

Important note: Whenever you change something in the model or regenerate the model code, you have to go through the entire generation chain—generate model code, schema and map, services, because the generated model code may not be complete or correct after just the model code generation. The services generation updates the generated model code. You can verify this on the one-to-one managedDepartment_manager association related relationship classes, which have isForward := true in

Page 164: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

their initialize method after the model code generation but true and false after the services generation. An error message like "...does not understand ...Key" indicates an incomplete forward generation chain.

138 Using VisualAge Smalltalk ObjectExtender

Figure 110. Rb30Department Class with Methods

7.3 Generate Schema and Mapping: Metadata and Database

Now you want to have ObjectExtender generate the schema and data store mappings for a database, or—once again—the image schema for the local image data store.

Page 165: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

If you want to use the local image data store, select Models->Create Image Schema from the menu bar in the Model Browser and continue with 7.6, “Run Sample Headless with Scripts” on page 146.

To generate the schema and mapping for a database, select Models-> Generate schema from model from the menu bar in the Model Browser.

Then review the generated schema and data store mappings using the Schema Browser and the Map Browser, respectively. If you already have these browsers open, you may have to refresh their lists. In the respective browser execute the Schemas->Load Available Schemas command and the Datastore Maps->Load Available Maps command from the menu bar to see the new schema and map.

7.3.1 Review the Schema and the MappingFigure 111 shows the Rb30Employee table of the generated schema. After you change the qualifier and adjust the column types and converters, the schema seems to be OK.

Employee and Department Top-Down 139

Figure 111. Generated Schema for Rb30EmployeeTable

Note: The table names in the logical name of the Foreign Key Relationships will not be used to generate the physical names for the constraints.

If your foreign keys for the one-to-one association are generated in the wrong table, go back to the model editor, delete the relevant association, and define the association again—in the reverse direction—and regenerate the schema. Force the update of the lists in the Schema Browser and Model Browser by

Page 166: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

executing the Schemas->Load Available Schemas... command and Datastore Maps->Load Available Maps... command, respectively.

Figure 112 shows the Rb30Department table of the generated schema. After you change the qualifier and adjust the column types, the schema seems to be OK.

Figure 112. Generated Schema for Rb30Department Table

Neither the schema nor the mapping requires structural changes.

Note: If you need to regenerate the schema because of an incorrect setup association, you must not only delete and reenter the incorrect setup association and delete the related Foreign Key Relationship; you also must delete the generated foreign key Column, because each generation itself adds its foreign key column.

7.3.2 Generate Conforming Physical NamesIt is possible to generate a physical database directly from the generated schema. However, you are almost certain to get some errors. These errors are in addition to the expected errors when the DROP TABLE commands are generated, as seen in Figure 55 on page 68.

When you try generating the database directly from the schema, the auto-generated ALTER TABLE ADD CONSTRAINT command fails because

140 Using VisualAge Smalltalk ObjectExtender

the foreign key names automatically generated by ObjectExtender do not conform to the database naming conventions—they either include spaces or are way too long. Another possible area of failure is the length of the automatically generated table and column names. These are usually limited by the particular database used. For DB2, table and column name lengths must not exceed 18 characters.

ObjectExtender provides basic support for generating DB2-conforming physical names. Evaluate this Smalltalk expression:

VapDatabasePhysicalRules applyToSchemaNamed: ’Rb30EmpDept’

Page 167: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Verify the result and change it—if it does not match your requirements—in the Column Editor (Figure 113, left) and in the Foreign Key Relationship Editor (Figure 113, right).

Figure 113. Table Column Editor and Foreign Key Relationship Editor

You open these editors in the Schema Browser either from the appropriate menu or by double-clicking on an item in the appropriate list.

In the Employee and Department Top-Down sample we extended the physical name generation support for DB2. Import VapDatabasePhysicalRulesApp

Employee and Department Top-Down 141

from Appendix 85, “Downloadable File RBOE.zip and Its Contents” on page 356 into your development repository and load it into your image. Start the extended generation in the System Transcript by selecting the new item, ObjectExtender Tools->Apply DB2 Physical Rules..., or by evaluating one of these Smalltalk expressions:

• VapDatabasePhysicalRules applyDB2Rules

• VapDatabasePhysicalRules singleton applyReasonablyToSchema:(VapSchema schemaNamed: ’Rb30EmpDept’

Page 168: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

When asked for the schema name, enter Rb30EmpDept. Table 15 lists the relevant methods for the name creation in VapDatabasePhysicalRules.

Table 16. VapDatabasePhysicalRules Class: Major Extending Methods

If you have already applied the basic naming support and want to try our extended naming support, either remove some or all of the physical names, or just delete the entire schema in the Schema Browser, regenerate the schema in the Model Browser, and apply our physical naming support. If the trace is on, each physical name that is either generated or changed is listed in the System Transcript Window (Figure 114).

VapDatabasePhysicalRules>>method ($=Class Method)

1 $applyDB2PhysicalRules- starts the generation and asks for the schema name in a message prompter

2 conformPhysicalName: actualPhysicalName from: nameOrSeedName for: anEntity- callback method for the call of the conformance and uniqueness methods (3 & 4)

3 conformPhysicalName: actualPhysicalName from: nameOrSeedName- builds the name, splits and truncates it

4 uniquePhysicalName: physicalName in: aSchema- makes the name unique in the schema

142 Using VisualAge Smalltalk ObjectExtender

Figure 114. Extended Physical Naming Support

Page 169: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

7.3.3 Match with the DB2 Sample Database (Optional)A few physical name changes and a flexible connection definition enable the Employee and Department sample to play not only with the self generated database but also with the DB2 sample database.

The following column name changes are mandatory:

• In the Rb30Employee table change the (physical) foreign key Rb30epartment_deptNo to workDept, to be in synch with the Department table of the DB2 sample database (Figure 81 on page 105).

• In the Rb30Department table change the (physical) foreign key name Rb30Employee_empNo to mgrNo and Rb30Department_deptNo to admrDept, to be in synch with the Department table of the DB2 sample database (Figure 137 on page 195).

Double-click on each of the columns in the Schema Browser to open the Column Editor and make the changes.

If you generate your table into a database other than the sample, you can change the table names to be in synch with the DB2 sample database tables EMPLOYEE and DEPARTMENT:

• Change the (physical) Rb30Employee table name to Employee.

• Change the (physical) Rb30Department table name to Department.

Double-click on each of the classes in the Schema Browser to open the Table Editor and make the changes.

If you have the rights to add aliases in the DB2 sample database, you do not have to change the table names. Just add aliases for the tables, such as USERID EMPLOYEE for the USERID RB30Employee table, and USERID DEPARTMENT for the USERID RB30Department table. If you use the DB2 UDB Control Center, expand the hierarchy down to the Aliases item and

Employee and Department Top-Down 143

select Create... from the pop-up menu.

7.3.4 Change the Column TypesUse the types listed in Table 17 to adjust the column types of the Rb30Employee table. Note that columns 5 and 14 are key columns that may produce an error and temporary inconsistencies (see 7.3.5, “Change the Key Column Types” on page 144). Use the VapTrimStringConverter for all

Page 170: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

characterlike columns to get the usual string behavior in Smalltalk for the entry fields and the concatenation.

Table 17. Columns for the Rb30Employee Table

Use the types listed in Table 18 to adjust the column types of the Rb30Department table. Note that columns 2, 4, and 5 are key columns that may produce an error and temporary inconsistencies when changed (see 7.3.5, “Change the Key Column Types” on page 144). Again, use the VapTrimStringConverter for all characterlike columns to get the usual string behavior in Smalltalk for the entry fields and the concatenation

Table 18. Columns for the Rb30Department Table

Column Name

Column Type with Length

Not Null

Column Name

Column Type with Length

Not Null

1 birthDate DATE No 8 job CHAR(8) No

2 bonus DECIMAL(9,2) No 9 lastName VARCHAR(15) Yes

3 comm DECIMAL(9,2) No 10 midInit CHAR(1) Yes

4 edLevel SMALLINT Yes 11 phoneNo CHAR(4) No

5 empNo CHAR(6) Yes 12 salary DECIMAL(9,2) No

6 firstNme VARCHAR(12) Yes 13 sex CHAR(1) No

7 hireDate DATE No 14 workDept CHAR(3) No

Column Name

Column Type with Length

Not Null

Column Name

Column Type with Length

Not Null

1 deptName VARCHAR(29) Yes 4 admrDept CHAR(3) Yes

2 deptNo CHAR(3) Yes 5 mgrNo CHAR(6) No

3 location CHAR(16) No

144 Using VisualAge Smalltalk ObjectExtender

7.3.5 Change the Key Column TypesType changes of columns that are not part of a foreign key relationship require no special consideration. The change is local to the table.

Type changes of columns that are part of foreign key relationships impact the column type definitions in the primary key tables as well as the foreign key tables. Ensure that you change all columns that are part of a foreign key relationship.

Page 171: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

ObjectExtender’s consistency check support prevents you from changing column types that are part of foreign key relationships. For details and how to work around or fix the strict implementation of the consistency check see Appendix F.2, “VapSchemaColumnEditorModel>> #areForeignKeysValid” on page 389.

Change all primary key column types and make the related foreign key column types match them.

Figure 115 shows foreign key relationships with inconsistent key type definitions.

Figure 115. Inconsistent Foreign Key Relationships

Note: For some unknown reason ObjectExtender did not generate NOT NULL for the column with the (logical) name Rb30Department_deptNo (Figure 115), even though we specified Required in the model (Figure 106 on page 134). Open the Column Editor and uncheck the Allow nulls check box (Figure 113 on page 141, left).

Finally, change the qualifier in the tables. Open a Class Editor by double-clicking on each table in the Tables list in the Schema Browser and change the qualifier to USERID (see Note on page 67).

Save the schema by selecting Schemas->Save Schema... from the menu bar in the Schema Browser. Use application name Rb30EmpDeptSchemaApp and storage class name Rb30EmpDeptSchema.

Employee and Department Top-Down 145

Save the mapping. Select Datastore_Maps->Save Datastore Map from the menu bar in the Map Browser to do so. Use application name Rb30EmpDeptMapApp and storage class name Rb30EmpDeptMap.

7.4 Generate Physical Database

You have now created a consistent model, schema, and data store map. Now you have to generate the physical database itself.

Page 172: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

You can preview the generated SQL code as an appendix to the textual summary of the schema by selecting Schemas->Generate DDL Script for Schema Creation from the menu bar of the Schema Browser. Copy and paste the SQL preview into a file and save the file for review with database designers, for later table (re-)creation outside ObjectExtender, or for the database administrator if he or she is the only one with the access rights to create database tables.

To create the tables, keys, and constraints in ObjectExtender, select Schemas->Import/Export Schema->Export Entire Schema to Database... from the menu bar in the Schema Browser. When you do this, you can use the System Transcript to check that the generated SQL code executed without errors, except for errors on the DROP TABLE commands if the tables do not currently exist. See Appendix D.2, “Rb30DBCR.txt - DB Table Creation Report” on page 365 for the generated and executed SQL code for the Employee and Department - Top-Down sample.

7.5 Generate Service Classes

The last step in generating the persistence support is to generate the service classes. In the Map Browser, select Datastore Maps->Generation Options from the menu bar to set the required generation options. In the database connection information specify only the Connection type, so you will be asked for the rest at runtime and you can select either your generated database or the DB2 sample database as the data source. For the code generation application specify the application name Rb30EmpDeptRb30empdeptServicesApp. Finally, perform the service class generation by selecting Datastore Maps->Generate Services from the menu bar.

At this point, we suggest versioning and releasing (and saving by exporting) the sample work you have done so far. See the steps in 5.3.3, “Version,

146 Using VisualAge Smalltalk ObjectExtender

Release, and Save the Sample Work” on page 60.

7.6 Run Sample Headless with Scripts

The run consists of two phases:

1. Set up sample objects2. Navigate the objects links

Figure 116 shows the objects that are created and navigated.

Page 173: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

department home employee home

DH EH

S1A (no mgr)

EMP1A1

EMP1A2

DeptS1B EMP1B0

EMP1B1Dept

S2A (no manager)

(no employees)Dept

TOP EMPTP0 (manager)

(no further employees)Dept

Top Level

Sublevel 1

(no administered

(no administered

DepartmentsA and B

Department

(home of the TOPand S... objects)

(home of the EMP... objects)

departments)

EMPXXX

(employee withno department)

Employee and Department Top-Down 147

Figure 116. Data Sample for Navigation

Each object has a name—all UPPERCASE and BOLD in the figure, for example, TOP and EMPTP0, that corresponds to the primary key of the object—if the object has one and is used to name temporary variables for the object in the scripts, for example vTOP and vEMPTP0, respectively.

The circular reference from the bottom to the top for the top-level department TOP, represents the special situation of the root element in the hierarchy given by the constraint: "Each element in the hierarchy must have a superior

departments)

Page 174: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

element." Review the definition made for this administers association on page 133 and in Figure 106 on page 134. Even if there are no sublevels, the top- level item has one subordinate: itself. This special situation is demonstrated with the 1st Transaction of the setup script.

The scripts to set up the sample objects and navigate them are downloadable as a workspace file, Rb30ObjW.wsp (see Appendix C, “Downloadables, ConfigMaps, Applications” on page 355.)

The script detects some problems and gives a short description of the solutions. For more details see appendixes:

• F.3, “Required Self-Associations” on page 391 • F.4.1, “Forward: Nil-Ability” on page 393 • F.4.2, “Backward: Individual Access Solution (Overriding)” on page 394

7.6.1 Set up Sample ObjectsThe setup part of the script below performs a global ObjectExtender reset and an activate of the data store—operations that can be also invoked from the Status Tool. After that, the sample objects are created and persisted in three transactions. If something goes wrong, execute the part of the script entitled CLEANUP and start over. You can also reexport the entire schema to the database. This reexport drops the tables and you have a clean restart.

Note that all association assignments use objects, not keys.

" Rb30ObW.wsp "" Rb30 Employee and Department Object setup and navigate Workspace "" ********************************************************************************* ""(in Tools set: Basic Trace, Enable Inspectors)"

" ================= BEG SETUP SCRIPTS ================= "

148 Using VisualAge Smalltalk ObjectExtender

• '01 Perform a global reset of ObjectExtender' vapTrace. [System vapReset.'' vapTrace ] value " --->"

• '02 Activate the Rb20EmployeeHome’’s data store.' vapTrace. [Rb30EmpDeptRb30empdeptDataStore singleton activate.'' vapTrace ] value " --->""Asks 3 times for a database connection specificationif the database connection is not completely defined.Choose 'Share'. ObjectExtender maintains several sessions."

Page 175: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

• '03 1st Trx: Add TOP department.' vapTrace. [| trx vTOP |trx := Transaction begin: '1st'.(vTOP := Rb30DepartmentHome singleton create)

deptNo: 'TOP';deptName: 'TOP Department'; location: 'TOP location';administrativeDepartment: vTOP.

trx commit. '' vapTrace ] value " --->"/////////////////////// DEBUGS - STACK OVERFLOW - ZAP ////////////////////////////////

a Rb30Department(nil)" ---> DEBUGGER with a STACK OVERFLOW! There is no way toovercome the stack overflow than to give ObjectExtender a small kick...:Complement the 'Resource>>#updateIndex:in:startingAt:' methodin the line 'aTargetBo notNil' with a recursion check to'aTargetBo notNil & (TargetBo ~~ version businessObject)',close the debugger, and re-execute step 03."

////////////////////////////////// REPEAT STEP 03 /////////////////////////////////////////////////////

• '04 Check TOP department. NOTE: Resume in the Debugger.' vapTrace. [| vTOP stream |System vapReset.Rb30EmpDeptRb30empdeptDataStore singleton activate.vTOP := Rb30DepartmentHome singleton findByDeptNo: 'TOP'.(stream := WriteStream on: String new)

nextPutAll: '* self: '; nextPutAll: vTOP printString;cr; nextPutAll: '* administrativeDepartment: ';

nextPutAll: vTOP administrativeDepartment printString;cr; nextPutAll: '* departments: ';

nextPutAll: (vTOP departments collect: [:d | d deptNo]) printString ;cr; nextPutAll: '* manager: '; nextPutAll: vTOP manager printString.

'Shows TOP with TOP in departments and as administrativeDepartment,and nil as manager' vapTrace.

self halt. "Double click on vTOP, employees, departments, stream,and swipe over list to see the values."

Employee and Department Top-Down 149

stream contents vapTrace. '' vapTrace ] value " ---->"

• '05 Add S1A, S2A, and S1B departments.' vapTrace. [| trx vTOP vS1A vS1B vS2A |System vapReset.Rb30EmpDeptRb30empdeptDataStore singleton activate.trx := Transaction begin: '2nd'.vTOP := Rb30DepartmentHome singleton findByDeptNo: 'TOP'.vS1A := Rb30DepartmentHome singleton create

deptNo: 'S1A';deptName: 'S1A Department'; location: 'S1A location';

Page 176: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

yourself.vS1B := Rb30DepartmentHome singleton create

deptNo: ’S1B’;deptName: ’S1B Department’; location: ’S1B location’;yourself.

vTOP addDepartments: vS1B.vS1A addDepartments: ( vS2A := Rb30DepartmentHome singleton create

deptNo: ’S2A’; deptName: ’S2A Department’; location: ’S2A location’;yourself ).

trx commit. ’’ vapTrace ] value " --->"

• '06 Add employees & managers except one to departments.' vapTrace. [| trx vTOP vS1A vS1B vEMPTP0 vEMP1B0 |System vapReset.Rb30EmpDeptRb30empdeptDataStore singleton activate.trx := Transaction begin: '3rd'.(vTOP := Rb30DepartmentHome singleton findByDeptNo: 'TOP')

addEmployees: ( (vEMPTP0 := Rb30EmployeeHome singleton create)empNo: 'EMPTP0'; edLevel: 0;firstNme: 'EMPTP0first'; midInit: 'T'; lastName: 'EMPTP0last';yourself );

manager: vEMPTP0.vTOP departments do: [ :dept | dept deptNo = 'S1A' ifTrue: [

deptaddEmployees: ( Rb30EmployeeHome singleton create

empNo: 'EMP1A1'; edLevel: 1;firstNme: 'EMP1A1first'; midInit: 'E'; lastName: 'EMP1A1last';yourself );

addEmployees: ( Rb30EmployeeHome singleton createempNo: 'EMP1A2'; edLevel: 1;firstNme: 'EMP1A2first'; midInit: 'E'; lastName: 'EMP1A2last';yourself ) ]

ifFalse: [ dept deptNo = 'S1B' ifTrue: [

150 Using VisualAge Smalltalk ObjectExtender

deptaddEmployees: ( (vEMP1B0 := Rb30EmployeeHome singleton create)

empNo: 'EMP1B0'; edLevel: 1;firstNme: 'EMP1B0first'; midInit: 'E'; lastName: 'EMP1B0last';yourself );

addEmployees: ( Rb30EmployeeHome singleton createempNo: 'EMP1B1'; edLevel: 1;firstNme: 'EMP1B1first'; midInit: 'E'; lastName: 'EMP1B1last';yourself );

manager: vEMP1B0 ] ] ].Rb30EmployeeHome singleton create

Page 177: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

empNo: ’EMPXXX’; edLevel: 1;firstNme: ’EMPXXXfirst’; midInit: ’E’; lastName: ’EMPXXXlast’.

trx commit. ’’ vapTrace ] value " --->"

• '07 Verify Object Setup - List Department Hierarchy with...' vapTrace. [| stack stream dept |System vapReset.Rb30EmpDeptRb30empdeptDataStore singleton activate.stream := WriteStream on: String new.(stack := OrderedCollection new) add: (Array with: 'TOP' with: '').[stack notEmpty] whileTrue: [ | ind |

ind := stack last at: 2.dept := Rb30DepartmentHome singleton findByDeptNo: (stack removeLast

at: 1).dept departments do: [ :d | d ~~ dept ifTrue: [stack add: (Array with: d

deptNo with: ind , '| ')] ].stream

cr; nextPutAll: ind; nextPutAll: '|---'; nextPutAll: dept printString;cr; nextPutAll: ind; nextPutAll: '| |---admrDept: '; nextPutAll: dept

administrativeDepartment printString;cr; nextPutAll: ind; nextPutAll: '| |---departments: '; nextPutAll: (dept

departments collect: [:s | s deptNo]) printString;cr; nextPutAll: ind; nextPutAll: '| |---manager: '; nextPutAll: (dept

manager ~~ nil ifTrue: [dept manager empNo] ifFalse: ['none']);cr; nextPutAll: ind; nextPutAll: '| |---employees: '; nextPutAll: (dept

employees collect: [:e | e empNo]) printString].

stream contents vapTrace. '' vapTrace ] value " --->"

" ================= END SETUP SCRIPTS ================= "

" =================== BEG CLEANUP ===================== "

Employee and Department Top-Down 151

• 'X1 Remove all managers from the departments.' vapTrace. [| trx |System vapReset.Rb30EmpDeptRb30empdeptDataStore singleton activate. trx := Transaction begin: 'X1'.Rb30DepartmentHome singleton allInstances do: [ :d |

d manager: nil ]. trx commit. '' vapTrace ] value " --->/////////////////////////////// MANAGERS STILL SET - ZAP /////////////////////////////////////

Change the generated method below(or change the generater class StRelation):

Page 178: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Rb1to1DepartmentToManagerRelationship>>#primGetForwardKeyForLink: aLink

"Get the forward key value to populate the passed link"| key |key := aLink source managerKey.aLink target isInitialTarget ifFalse: [

key := key class new ].^key

////////////////////////////////// REPEAT STEP X1 /////////////////////////////////////////////////////

• 'X2 Remove all employees.' vapTrace. [| trx |System vapReset.Rb30EmpDeptRb30empdeptDataStore singleton activate. trx := Transaction begin: 'X2'.Rb30EmployeeHome singleton allInstances do: [ :e |

e markRemoved ]. trx commit. '' vapTrace ] value " --->"

• 'X3 Remove the departments recursively from bottom in single Trx’’s.'vapTrace. [

| trx dept |System vapReset.Rb1toMSelfReqRb1tomselfreqDataStore singleton activate.trx := Transaction begin: 'X3'.dept := Rb1toMSRDepartmentHome singleton findByDeptNo: 'TOP'.[dept ~~ nil] whileTrue: [ | departmentsTemp deptTemp deleteTrx |

(departmentsTemp := dept departments) isEmpty ifTrue: [(deptTemp := dept administrativeDepartment)

removeDepartments: dept. dept markRemoved; vapTrace.

trx commit. trx := Transaction begin: 'X3...'.dept := deptTemp ]

ifFalse: [dept := dept ~~ (deptTemp := departmentsTemp first)

ifTrue: [deptTemp] "first is last on top"

152 Using VisualAge Smalltalk ObjectExtender

ifFalse: [ dept ~~ (deptTemp := departmentsTemp last)ifTrue: [ deptTemp]ifFalse: [dept markRemoved; vapTrace. nil] ] ] ]. "TOP"

trx commit. '' vapTrace ] value " --->"

" =================== END CLEANUP ===================== "

Look at the downloadable workspace file Rb30ObjW.wsp (Appendix C, “Downloadables, ConfigMaps, Applications” on page 355) to see the the

Page 179: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

complete System Transcript output. The following extracts are from the following two steps:

• 04 Check TOP department

• 07 Verify Object Setup - List Department Hierarchy with Contents

Note that the employee entry EMPXXX does not show up, because its department attribute is nil (and the managedDepartment returns nil too).

" ============= TRANSCRIPT OUTPUT =================== "

• (04 Check Top Department.)

'Shows TOP with TOP in departments and as administrativeDepartment,and nil as manager'

'* self: a Rb30Department(''TOP'')* administrativeDepartment: a Rb30Department(''TOP'')* departments: OrderedCollection(’’TOP’’ )* manager: nil’

• (07 Verify Object Setup - List Department Hierarchy with Contents)

|---a Rb30Department(’’TOP’’)| |---admrDept: a Rb30Department(''TOP'')| |---departments: OrderedCollection(''TOP'' ''S1A'' ''S1B'' )| |---manager: EMPTP0| |---employees: OrderedCollection(''EMPTP0'' )| |---a Rb30Department(’’S1B’’)| | |---admrDept: a Rb30Department(''TOP'')| | |---departments: OrderedCollection()| | |---manager: EMP1B0| | |---employees: OrderedCollection(''EMP1B0'' ''EMP1B1'' )| |---a Rb30Department(’’S1A’’)| | |---admrDept: a Rb30Department(''TOP'')

Employee and Department Top-Down 153

| | |---departments: OrderedCollection(''S2A'' )| | |---manager: none| | |---employees: OrderedCollection(''EMP1A2'' ''EMP1A1'' )| | |---a Rb30Department(’’S2A’’)| | | |---admrDept: a Rb30Department(''S1A'')| | | |---departments: OrderedCollection()| | | |---manager: none| | | |---employees: OrderedCollection()'''

Figure 117 shows the "self halt." in the step 04 Check Top Department.

Page 180: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 117. Inspecting the TOP Department in the Debugger

7.6.2 Navigate the ObjectsTo navigate objects, you need to know which methods are available to help you. Use the VisualAge Organizer and the Class Editor to look at the application and classes where the model code is stored. For a first example, Figure 118 shows the methods available in the Rb30DepartmentHome class of the Rb30EmpDeptApp application for creating and accessing departments.

154 Using VisualAge Smalltalk ObjectExtender

Page 181: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 118. Access Methods Implemented by Rb30DepartmentHome

You can see the simple and inherited create method (Figure 119) when you change the method visibility to the immediate superclass by selecting Methods->Visibility->To Named Class... from the menu bar and selecting PersistentHomeCollection in the selection dialog.

Employee and Department Top-Down 155

Figure 119. Usual Access Methods of Rb30DepartmentHome

Page 182: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

As a second example, Figure 120 shows the methods available in the Rb30Department class of the Rb30EmpDeptApp application for accessing the associated objects.

Figure 120. Access Methods of Rb30Department

You can use the same approach to find out which methods are available for the other objects.

156 Using VisualAge Smalltalk ObjectExtender

For Employee and Department sample, you have to test the following six navigation cases which are related to the three bidirectional navigable associations:

1. Find the departments for a department (if any).2. Find a department’s administrative department (there must be one).3. Find employees for a department (if any).4. Find an employee’s department (if any).5. Find the manager (if any) of a department.6. Find the department (if any) an employee manages.

Page 183: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

To carry out these tests, it is only necessary to have read access to the database. Therefore perform the tests within the context of the global shared transaction, without begining or committing a transaction. Start the sequence by executing this Smalltalk expression:

• 'N0 Setup Navigate (OE general reset, data store activate.' vapTrace. [ System vapReset.Rb30EmpDeptRb30empdeptDataStore singleton activate.'' vapTrace ] value " --->"

Finding the Departments for a Department (If Any)Obviously, there are roughly two kinds of departments: those that administer others (S1A and TOP), and those that do not (S1B, and S2A)—so-called nodes and leaves. The element on the top is called root and also administers itself—a given for this Employee and Department sample. In the unusual case of a single department, the root is a special leaf administering only itself. This was the situation when we checked the TOP department after adding it (page 149).

Executing the following Smalltalk expressions:

• 'N1a Find the departments of the S1A department.' vapTrace. [( ( Rb30DepartmentHome singleton findByDeptNo: 'S1A')

departments collect: [:d | d deptNo] ) vapTrace.'' vapTrace ] value " --->"

• 'N1b Find the departments of the S1B department.' vapTrace. [( ( Rb30DepartmentHome singleton findByDeptNo: 'S1B')

departments collect: [:d | d deptNo] ) vapTrace.'' vapTrace ] value " --->"

• 'N1c Find the departments of the TOP department.' vapTrace. [( ( Rb30DepartmentHome singleton findByDeptNo: 'TOP')

departments collect: [:d | d deptNo] ) vapTrace.'' vapTrace ] value " --->"

Employee and Department Top-Down 157

you should get the following output in the System Transcript (some lines of the trace, such as the SQL, have been removed from the output, but are visible in the downloadable script file):

• for N1a—S1A departments: OrderedCollection('S2A') • for N1b—S1B departments: OrderedCollection() • for N1c—TOP departments: OrderedCollection('TOP' 'S1A' 'S1B' )

Note that the TOP department is included its departments.

Page 184: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Finding a Department’s Administrative DepartmentEvery department has an administrative department—the root or TOP department itself also has an administrative department.

Executing the following Smalltalk expressions:

• 'N2a Find the administr. dept. of the S1A department.' vapTrace. [(Rb30DepartmentHome singleton findByDeptNo: 'S1A')

administrativeDepartment deptNo vapTrace.'' vapTrace ] value " --->"

• 'N2b Find the administr. dept. of the TOP department.' vapTrace. [(Rb30DepartmentHome singleton findByDeptNo: 'TOP')

administrativeDepartment deptNo vapTrace.'' vapTrace ] value " --->"

you should get the following output in the System Transcript (again, some lines of the trace have been removed):

• for N2a—S1A’s administrative Department: 'TOP' • for N2b—TOP’s administrative Department: 'TOP'

Finding Employees for a Department (if Any)Executing the following Smalltalk expressions:

• 'N3a Find the employees of the S1B department.' vapTrace. [( (Rb30DepartmentHome singleton findByDeptNo: 'S1B')

employees collect: [:e | e empNo] ) vapTrace.'' vapTrace ] value " --->"

• 'N3b Find the employees of the S2A department.' vapTrace. [( (Rb30DepartmentHome singleton findByDeptNo: 'S2A')

employees collect: [:e | e empNo] ) vapTrace.'' vapTrace ] value " --->"

you should get the following output in the System Transcript:

158 Using VisualAge Smalltalk ObjectExtender

• for N3a—S1B’s employees: OrderedCollection('EMP1B0' 'EMP1B1' ) • for N3b—S2A’s employees: OrderedCollection()

Finding an Employee’s Department (If Any)Executing the following Smalltalk expressions:

• 'N4a Find the work department of empl. EMP1B0 (if any).' vapTrace. [(Rb30EmployeeHome singleton findByEmpNo: 'EMP1B0')

workDepartment vapTrace.'' vapTrace ] value " --->"

Page 185: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

• 'N4b Find the work department of empl. EMPXXX (if any).' vapTrace. [(Rb30EmployeeHome singleton findByEmpNo: 'EMPXXX')

workDepartment vapTrace.'' vapTrace ] value " --->"

you should get the following output in the System Transcript:

• for N4a—EMP1B0’s work department: a Rb30Department('S1B') • for N4b—EMPXXX’s work department: nil

Note that a non-required association returns nil if not set—the work department of employee EMPXXX is not set.

Finding the manager (if any) of a departmentExecuting the following Smalltalk expressions:

• 'N5a Find the manager of the S1B department (if any).' vapTrace. [(Rb30DepartmentHome singleton findByDeptNo: 'S1B')

manager vapTrace.'' vapTrace ] value " --->"

• 'N5b Find the manager of the S1A department (if any).' vapTrace. [(Rb30DepartmentHome singleton findByDeptNo: 'S1A')

manager vapTrace.'' vapTrace ] value " --->"

you should get the following output in the System Transcript:

• for N5a—S1B’s manager: a Rb30Employee('EMP1B0') • for N5b—S1A’s manager: nil

Note that a non-required association returns nil if not set—the work department of employee EMPXXX is not set.

Finding the Department (If Any) an Employee Manages

Employee and Department Top-Down 159

Obviously, there are two kind of employees: those who manage a department (EMPTP0 and EMP1B0) and those who do not (EMP1A1 EMP1A2, and EMP1B1. This time the script not only vapTraces to the System Transcript but also opens an inspector on the result object.

Before you execute the scripts, import the V2.0 [ JRW 09/07/98 ] a version of the VapInspectorUtilitiesApp of the downloadable library, RBOED.DAT, into your library, load it into your image, and enable the inspectors (see Appendix C, “Downloadables, ConfigMaps, Applications” on page 355 and 3.4, “Inspectors” on page 38).

Page 186: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Executing the following Smalltalk expressions:

• 'N6a Find the managed department of EMP1B0 (if any).' vapTrace. [( (Rb30EmployeeHome singleton findByEmpNo: 'EMP1B0')

managedDepartment ) vapTrace; inspect.'' vapTrace ] value " --->"

• 'N6b Find the managed department of EMP1B1 (if any).' vapTrace. [( (Rb30EmployeeHome singleton findByEmpNo: 'EMP1B1')

managedDepartment vapTrace ) inspect.'' vapTrace ] value " --->"

you should get the following output in the System Transcript (after working through Appendix F.4.2, “Backward: Individual Access Solution (Overriding)” on page 394)":

• for N5a—S1B’s manager: a Rb30Employee('EMP1B0') • for N5b—S1A’s manager: nil

and for N5a the Inspector as shown in Figure 121.

Note that a non-required association returns nil if the backward link is not set—the manager of department S1A is not set.

160 Using VisualAge Smalltalk ObjectExtender

Figure 121. Version V0.2... Enabled Inspector on the S1B Department

Note that the V0.2 [ JRW 09/07/98 ] a version enabled inspector does not show the instance variable values, in contrast to the version V0.1 [ JRW 08/28/98 ] a (Figure 122).

Page 187: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 122. Version V0.1... Enabled Inspector on the S1B Department

7.7 Run Sample with User Interface

Now you add GUIs to support the persistent classes. The first GUI is a single-window GUI and supports the creation and maintenance of employees of a given set of departments. The second GUI follows the same ideas introduced in Figure 94 on page 115. Create the Rb30EmpDeptViewApp for all Rb30 prefixed views.

7.7.1 Single Window GUI for Employee Creation and MaintenanceThe single window GUI (Figure 123; connections in Table 19 on page 163) is derived from the Rb20EmployeeView in Figure 71 on page 84 (for the window layout) and Figure 75 on page 92, second from top (for the use of the transactions).

As the workDepartment of an employee must be taken from the list of available departments, a drop-down list box is used to display the current department (selectedItem) and other available departments (items). The

Employee and Department Top-Down 161

available departments are supplied by the departmentHome’s allInstances. The displayed attribute in the drop-down list box can be the deptNo, or—more flexible as discussed in the next paragraph—referenceString.

Because the workDepartment of an employe is now a department object and no longer just a string (foreign key), the list column with the header workDept and the employee need to be changed. It is convenient and a good practice to define a printable, derived, read-only attribute for reference purposes in lists that display more than just the object ID or another single attribute. A natural name for this printable, derived, read-only, string

Page 188: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

attribute is referenceString, and if it is a promoted value, such as the referenceString of the workDepartment of the employee, the origin is added as a prefix, such as the workDepartmentReferenceString. For the definitions of the convenience methods see 7.7.2, “Convenience Attributes and Methods” on page 164.

162 Using VisualAge Smalltalk ObjectExtender

Figure 123. Single Window View: Rb30EmployeeView

Page 189: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 19. Connections of Rb30EmployeeView

Source (S) Feature of S Target (T) Feature of T

123

businessTransactionbusinessTransaction(businessTransaction,transaction --> containerEmployees,items)

transactiontransactionvalue

employeecontainerEmployeesemployeeHome

transactionitemsallInstances

4567

concatenatorcontainerEmployeescontainerEmployeesdepartmentHome

stringselectedItemselectionIsValidallInstances

WindowemployeepbMarkForDeletedropDownDepartments

titleselfenableditems

89

101112

employeeemployeeemployeeemployeeemployee

birthDatelastNamemidInitphoneNojob

birthDateFieldlastNameFieldmidInitFieldphoneNoFieldjobField

objectobjectobjectobjectobject

1314151617

employeeemployeeemployeeemployeeemployee

commbonussalaryedLevelsex

commFieldbonusFieldsalaryFieldedLevelFieldsexField

objectobjectobjectobjectobject

1819202122

employeeemployeeemployeeemployeeemployee

empNofirstNmehireDateisPersistentisNotPersistent

empNoFieldfirstNmeFieldhireDateFieldtbIsPersistenttrueElseFalse

objectobjectobjectselectionboolean

2324252627

employeeemployeeemployeeemployeeHomenotNil

selfworkDepartmentfullNameallInstancesnotNil

notNildropDownDepartmentsconcatenatorcontainerEmployeesscrolledForm

objectselectedItemstring1itemsenabled

28 pbCancel clicked businessTransaction rollback

Employee and Department Top-Down 163

29 pbMarkForDelete clicked employee remove

3031

pbNew(pbNew,clicked --> employeeHome,create)

clickednormalResult

employeeHomeemployee

createself

3233

pbSave(pbSave,clicked --> businessTransaction,commit)

clickederrorResult

businessTransactionerrorPrompter

commitpromptFor:

34 trueElseFalse trueElseFalse empNoField editable

Page 190: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

7.7.2 Convenience Attributes and MethodsA view of an object has to display not only stored values, such as strings and numbers, but also references to associated objects. To make the GUIs consistent and the objects easy to use, it is a good practice and convenient to define for each object:

• One attribute called referenceString that is a printable string and a clueful reference to the object

• Attributes called xyzReferenceString—one for each associated object xyz—that are the (promoted) reference strings of the associated objects

and implement the corresponding method.

For the Employee the reference string attributes are:

• referenceString built from the empNo lastName, firstName, and midInit

• managedDepartmentReferenceString promoted from the managedDepartment

• workDepartmentReferenceString promoted from the workDepartment

For the Department the reference string attributes are:

• referenceString built from the deptNo, and deptName

• administrativeDepartmentReferenceString promoted from the administrativeDepartment

• managerReferenceString promoted from the manager (employee)

You can also think of more than one reference string attribute for an object, such as fullName for the Employee. In many places, where you want to show an employee reference, the natural composition of the fullname: "firstNme midInit. lastName" is not convenient.

Define the attributes in the Public Interface Editor (Figure 124). Define them

164 Using VisualAge Smalltalk ObjectExtender

as read-only because they are all derived from other attributes or objects. An attribute is defined as read-only by a blank Set selector. Note that the Event symbol is defined. It is required to signal changes when the attribute’s sources are changed.

Page 191: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 124. The Read-Only referenceString Attribute in the Public Interface Editor

Generate the default methods (scripts) but no instance variables for the

Employee and Department Top-Down 165

attributes, and complete the generated default methods as shown in Table 20 on page 166 and Table 22 on page 168. Categorize the methods in the category OERedbook, because categorizing is also a good practice.

Add the signaling for the derived attributes in the user code {post-Set} area of the setter methods of the contributing attributes (Table 21 on page 167 and Table 22 on page 168) and categorize the changed Generated Accessors also in

Page 192: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

the category OERedbook-modified. Note that methods 7 to 10 in Table 21 on page 167 are private.

Table 20. Reference String and fullName Methods of Employee

Rb30Employee>>#methods in category OERedbook

1 referenceString"Return the value of referenceString."| stream tempMidInit |^(stream := WriteStream on: String new)

nextPutAll: self empNo;nextPut: $ ;nextPutAll: self lastName;nextPutAll: ’, ’;nextPutAll: self firstNme;nextPutAll: ( (tempMidInit := self midInit asString) notEmpty

ifTrue: [stream nextPut: $ ; nextPut: tempMidInit first. ’.’]ifFalse: [’’] );

contents

2 workDepartmentReferenceString"Return the value of workDepartmentReferenceString."^self workDepartment referenceString

3 managedDepartmentReferenceString"Return the value of managedDepartmentReferenceString."^self managedDepartment referenceString

4 fullName"Return the value of fullName."| stream tempMidInit |^(stream := WriteStream on: String new)

nextPutAll: self firstNme;nextPut: $ ;nextPutAll: ( (tempMidInit := self midInit asString) notEmpty

ifTrue: [stream nextPut: tempMidInit first. ’. ’]ifFalse: [’’] );

nextPutAll: self lastName;

166 Using VisualAge Smalltalk ObjectExtender

contents

Page 193: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 21. Employee Modifications to Signal Changes of Derived Attributes

Rb30Employee>>#methods in categery OERedbook-modified

5

>>

managedDepartment: aRb30Department "Set the value of the association managedDepartment in the current transaction."

"Begin user code {pre-Set}""End user code"

self bom markModified.self managedDepartmentLink connectTo: aRb30Department.

"Begin user code {post-Set}"self signalEvent: #managedDepartmentReferenceStringwith: self managedDepartmentReferenceString."End user code"

self signalEvent: #managedDepartment with: aRb30Department

6

>>

workDepartment: aRb30Department ...

self signalEvent: #workDepartmentReferenceStringwith: self workDepartmentReferenceString.

...

7 primEmpNo: aString ...

self signalEvent: #referenceStringwith: self referenceString.

...

8

>>

primFirstNme: aString ...

self signalEvent: #referenceString.self signalEvent: #fullName with:self fullName.

...

9 primLastName: aString

Employee and Department Top-Down 167

>>

...self signalEvent: #referenceString.self signalEvent: #fullName with:self fullName.

...

10

>>

primMidInit: aString ...

self signalEvent: #referenceString.self signalEvent: #fullName with:self fullName.

...

Page 194: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 22. Department referenceString Methods

Rb30Department>>#methods in category OERedbook

1 referenceString"Return the value of referenceString."

^(WriteStream on: String new) nextPutAll: self deptNo;nextPut: $-;nextPutAll: self deptName;contents

2 administrativeDepartmentReferenceString"Return the value of administrativeDepartmentReferenceString."

^self administrativeDepartment referenceString

3 managerReferenceString"Return the value of managerReferenceString."

^self manager referenceString

168 Using VisualAge Smalltalk ObjectExtender

Page 195: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 23. Department Modifications to Signal Changes of Derived Attributes

Note that methods 6 and 7 in Table 23 are private.

Rb30Employee>>#methods in categery OERedbook-modified

4

>>

administrativeDepartment: aRb30Department "Set the value of the association administrativeDepartment in the current trx."

"Begin user code {pre-Set}""End user code"

self bom markModified.self administrativeDepartmentLink connectTo: aRb30Department.

Begin user code {post-Set}"self signalEvent: #administrativeDepartmentReferenceString

with: self administrativeDepartmentReferenceString."End user code"

self signalEvent: #administrativeDepartment with: aRb30Department

5

>>

manager: aRb30Employee ....

self signalEvent: #managerReferenceStringwith: self managerReferenceString.

....

6

>

primDeptName: aString ...

self signalEvent: #referenceString with: self referenceString....

7

>

primDeptNo: aString ....

self signalEvent: #referenceString with: self referenceString.....

Employee and Department Top-Down 169

You may be wondering why methods 2 and 3 of the employee (Table 20 on page 166) and method 3 of the department (Table 22 on page 168) do not check nil. The UndefinedObject nil has an extension in application Rb99VasXOeApp that makes the nil-check obsolete (Table 24).

Table 24. UndefinedObject Extension referenceString

UndefinedObject>>#referenceString

referenceString

^’~none’

Page 196: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

7.7.3 GUI with List and Detail Views Supporting Drag and DropThe GUI with list and detail views follows the concept explained in 6.5, “Adding the User Interface” on page 115 with two additions:

• Drag-source support in list views

• Reusable form with drag and drop support for single references in detail views

• Detail views with drag and drop support

Drag-Source Support in List Views The Rb30DepartmentListView (Figure 125) and Rb30EmployeeListView (Figure 126) are built the same way as the Rb21EmployeeListView (Figure 95 on page 116) in 6.5.1, “Create a List View” on page 116. The only major difference—besides the prefix Rb30 and the additional Department scope—is the use of the reference string attribute names for the attributeName setting of the container detail columns, and the drag-source support in the actual list. The reference string attributes in the view are used to achieve a reasonable display of the references.

170 Using VisualAge Smalltalk ObjectExtender

Figure 125. Rb30DeaprtmentListView

Page 197: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 126. Rb30EmployeeListView

The manager, admrDept (administrativeDepartment), wDept (workDepartment), and mgdDept (managedDepartment) columns use the reference string names in their attributeName settings. The reference strings are described in 7.7.2, “Convenience Attributes and Methods” on page 164. Table 12 on page 118 lists the connections.

Reusable Form with Drag and Drop Support for Single ReferencesA read-only entry field is sufficient to display the reference string of a

Employee and Department Top-Down 171

referenced object in a detail view, but not for the assignment of a reference. The form Rb99SingleReferenceForm (Figure 127) in Rb90UtilityViewsApp supports drag-source and drag-target operations and is the replacement for read-only entry field or drop-down lists for single references as used in, for example, Rb30EmployeeView in Figure 123 on page 162.

The Rb99SingleReferenceForm is used in the Rb31EmployeeDetailView (Figure 131 on page 180) for the workDept and mgdDept (managedDepartement) reference. In the Rb31DepartmentDetailView (Figure 129 on page 176) it is used for admrDept (administrativeDepartment) and manager references.

Page 198: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

As opposed to the entry field’s String object, from the referenced object the reference form’s object is the referenced object itself. Therefore the connection of the referenceString feature of the business object to the object of the entry field is replaced with the connection from the object reference feature to the referenceObject feature of the reference part in the form. To supply the display functionality of the entry field, namely, the display of the reference string of the referenced object, the reference part in the form promotes the referenceObject and the referenceAttributeName. The referenceAttributeName has to be specified at edit time and has the default value referenceString.

Note: The reference part is an AbtListView part and needs special care for the drag and drop, because it features only strings in the standard drag and drop support. The scripts in Table 26 on page 174, the orderedCollection variable, and the OrderedCollection Factory provides the special care. We chose AbtListView part for the reference part because of the easy use of its already built-in select and drag-and-drop support.

1. 3.2.

172 Using VisualAge Smalltalk ObjectExtender

Figure 127. Rb99SingleReferenceForm with Drag and Drop Support

Page 199: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The Clear and List menu choices are to reset the referenceObject to nil and fire the referenceList event to, for example, open the list of all objects available for a reference.

For more information about the Rb99SingleReferenceForm part consult the following items:

• Figure 128—shows the parts list.

• Table 25 on page 174—lists the connections.

• Table 26 on page 174—lists the events and scripts of the drag and drop supporting reference event-to-script connections.

• Table 27 on page 175—lists all promoted features.

Figure 128. Rb99SingleReferenceForm Parts List

Employee and Department Top-Down 173

Page 200: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 25. Connections of Rb99SingleReferenceForm

Table 26. Drag and Drop Support Events and Scripts in Rb99SingleReferencesForm

Source (S) Feature of S Target (T) Feature of T

12

menuChoiceClearmenuChoiceClear

clickedclicked

referenceObjectorderedCollection

selfremoveAtIndex:

3 orderedCollection self reference items

4 reference dragStartRequested

Rb99SingleReferenceForm dragStartRequested:

5 reference dragOver Rb99SingleReferenceForm dragOver:

6 reference dropped Rb99SingleReferenceForm dropped:

7 referenceObject self OrderedCollection new

8 (referenceObject,self --> OrderedCollection,new)

normalResult orderedCollection self

9 (referenceObject,self --> OrderedCollection,new)

normalResult orderedCollection add:

10 ( (referenceObject,self --> OrderedCollection,new),normalResult --> orderedCollection,add:)

anObject referenceObject self

11 referencePpopUpMenu self reference menu

Event of reference Subpart Script

1 dragStartRequested dragStartRequested: aDragDrop"Add the dragged object."aDragDrop sourceItems

add: (self subpartNamed: ’referenceObject’) items first

2 dragOver dragOver: aDragDrop

174 Using VisualAge Smalltalk ObjectExtender

"Return the drop vote."( (aDragDrop sourceItems size == 1)& ( (self subpartNamed: ’reference’)

abtAtAttribute: #dropAcceptableClassList )includes: aDragDrop sourceItems first class)

ifTrue: [aDragDrop vote: #(3)]ifFalse: [aDragDrop vote: #()]

3 dropped dropped: aDragDrop"Drop to the reference object."(self subpartNamed: ’referenceObject’)

value: aDragDrop sourceItems first

Page 201: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 27. Promoted Features in Rb99SingleReferenceForm

Feature Name Subpart Name [Class] (Promoted Feature) Type:

Purpose

1 referenceObject referenceObject [AbtVariable] (self) attribute:

variable to hold the referenced object (for example, the workdepartment of an employee)

2 referenceAttributeName reference [AbtListView] (attributeName) attribute:

name of the attribute to display (a symbol, for example: referenceString)

3 referenceDefaultActionRequested reference [AbtListView] (defaultActionRequested) event:

event fired on the double-click to, for example, open a detail view on the referenceObject

4 referenceAcceptableDropClassList reference [AbtListView] (acceptableDropClassList) attribute:

an OrderedCollection of classes that are accepted as drop items to set up the reference to

5 referenceNillable menuChoiceClear [AbtPushButtonView] (enabled) attribute:

boolean to enable the menu choice for the reset (set to nil) of the reference object

6 referenceListEnabled menuChoiceList [AbtPushButtonView] (enable) attribute:

boolean to enable a search and list view on available reference objects to select and drag from

Employee and Department Top-Down 175

7 referenceListClicked menuChoiceList [AbtPushButtonView] (clicked) event:

event to open a search and list view on available reference objects to select and drag from

Page 202: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Detail Views with Drag and Drop SupportRb30DepartmentDetailView (Figure 129) and Rb30EmployeeDetailView (Figure 131) are built the same way as Rb21EmployeeDetailView (Figure 96 on page 119) in 6.5.2, “Create a Detail View” on page 119.

176 Using VisualAge Smalltalk ObjectExtender

Figure 129. Rb30DepartmentDetailView

Figure 129 shows the Rb30DepartmentDetailView parts list.

Page 203: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Employee and Department Top-Down 177

Figure 130. Rb30DepartmentDetailView Parts List

Page 204: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The only major differences—besides the prefix Rb30 and the additional Department scope—are:

• The use of Rb99SingleReferenceForm for the referenced objects, such as the admrDept (administrativeDepartment), manager, mgndDepartment (managedDepartment), and workDept (workDepartment)

• The list support for objects that can be referenced

• The drag and drop support in multiple references (lists), such as the list of administered departments and employees

• The hasModifications support to indicate whether there are modified objects in the transaction

• TheunsavedChanges support on the window close request with the options save, discard, and cancel

• The transaction name display support

• The Department specific support to set the self reference in a root department.

The drag and drop support for multiple references (lists) needs the connections from the dropped and dragCompletedRequest events to the new dragged... and dropped... methods of the Department (Table 28 on page 179).

The new methods are required, because the standard drag and drop implementation expects the removeAll: and addAll: protocol of the Collection, which is not understood by ObjectExtender’s LinkCollection.

The new methods are defined as actions in the public interface. The public interface definitions of the departments and employees read-only attributes must be completed with the event symbols so that the drag and drop action shows updates.

For the required ObjectExtender modifications and extensions to enable the

178 Using VisualAge Smalltalk ObjectExtender

hasModifications support, see Appendix F.6, “Transaction>>#hasModifications Support” on page 400.

For the transaction name display support, see Appendix F.7, “Transaction Name Form” on page 405.

The spider webs of the Rb30DepartmentDetailView in Figure 129 on page 176 and Rb30EmployeeDetailView in Figure 131 on page 180, the parts list in Figure 132 on page 181 and, and the connections listed in Table 29 on page 182 through Table 35 on page 188 make the need for simplification obvious (see comment on page 94). The Rb99SingleReferenceForm could incorporate

Page 205: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

the opening of the detail and list view, and a Rb99MultipleReferenceForm could be built to support drag-drop supported lists with opening of the items detail and list view.

Table 28. Rb30Department Methods for the Drag-Drop Support

Rb30Department

1 draggedDepartments: aDragDrop

"Perform the draggedDepartments action."

self signalEvent: #departments with: self departments

2 droppedDepartments: aDragDrop

"Perform the droppedDepartments action."

aDragDrop sourceItems do: [ :si |self addDepartments: si ].

self signalEvent: #departmentswith: self departments

4 draggedEmployees: aDragDrop

"Perform the draggedEmployees action."

self signalEvent: #employeeswith: self employees

5 droppedEmployees: aDragDrop

"Perform the droppedEmployees action."

aDragDrop sourceItems do: [ :si |self addEmployees: si ].

self signalEvent: #employeeswith: self employees

Employee and Department Top-Down 179

Page 206: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 131. Rb30EmployeeDetailView

Figure 132 shows the Rb30EmployeeDetailView parts list.

180 Using VisualAge Smalltalk ObjectExtender

Page 207: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Employee and Department Top-Down 181

Figure 132. Rb30EmployeeDetailView Parts List

Page 208: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 29. Connections of the Rb30DepartmentDetailView (Part 1 of 4)

Source (S) Feature of S Target (T) Feature of T

1 admrDeptIsNil isNilObject department administrativeDepartment

2 (admrDeptIsNil,isNilObject --> department,administrativeDepartment)

value department self

3 admrDeptReferenceForm referenceDefaultActionRequested

DepartmentDetailView new

4 admrDeptReferenceForm referenceListClicked DepartmentListView new

5 (admrDeptReferenceForm,referenceDefaultActionRequested --> DepartmentDetailView,new)

normalResult departmentDetailView modelTmp

6 (admrDeptReferenceForm,referenceDefaultActionRequested --> DepartmentDetailView,new)

normalResult departmentDetailView openWidget

7 ((admrDeptReferenceForm,referenceDefaultActionRequested --> DepartmentDetailView,new),normalResult --> departmentDetailView,modelTmp)

value admrDeptReferenceForm object

8 businessTransaction transaction department transaction

9 businessTransaction hasModifications pbCancel enabled

10 businessTransaction hasModifications hasModifications boolean

11 concatenator string Window title

12 containerDepartments defaultActionRequested

DepartmentDetailView new

13 containerDepartments dropped department droppedDepartments

182 Using VisualAge Smalltalk ObjectExtender

14 containerDepartments dragCompleteRequested

department draggedDepartments

15 (containerDepartments,defaultActionRequested --> DepartmentDetailView,new)

normalResult departmentDetailView modelTmp

16 (containerDepartments,defaultActionRequested --> DepartmentDetailView,new)

normalResult departmentDetailView openWidget

Page 209: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 30. Connections of the Rb30DepartmentDetailView (Part 2 of 4)

Source (S) Feature of S Target (T) Feature of T

17 ((containerDepartments,defaultActionRequested --> DepartmentDetailView,new),normalResult --> departmentDetailView,modelTmp)

value containerDepartments selectedItem

18 containerEmployees defaultActionRequested

EmployeeDetailView new

19 containerEmployees dropped department droppedEmployees

20 containerEmployees dragCompleteRequested

department draggedEmployees

21 containerEmployees selectionIsValid employeesMenuChoiceRemove

enabled

22 (containerEmployees,defaultActionRequested --> EmployeeDetailView,new)

normalResult employeeDetailView employeeTmp

23 (containerEmployees,defaultActionRequested --> EmployeeDetailView,new)

normalResult employeeDetailView openWidget

24 ((containerEmployees,defaultActionRequested --> EmployeeDetailView,new),normalResult --> employeeDetailView,employeeTmp)

value containerEmployees selectedItem

25 deleteConfirmer okYesRetry department remove

26 deleteConfirmer okYesRetry businessTransaction commit

27 (deleteConfirmer,okYesRetry --> businessTransaction,commit)

normalResult Window closeWidget

28 department isNotPersistent trueElseFalse boolean

Employee and Department Top-Down 183

29 department isPersistent pbDelete enabled

30 department departments containerDepartments items

31 department employees containerEmployees items

32 department deptNo deptNoField object

33 department deptName deptNameField object

34 department location loacationField object

35 department self deptNotNil object

Page 210: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 31. Connections of the Rb30DepartmentDetailView (Part 3 of 4)

Source (S) Feature of S Target (T) Feature of T

36 department referenceString concatenator string2

37 department administrativeDepartment

admrDeptReferenceForm

referenceObject

38 department manager mgrReferenceForm referenceObject

39 department transaction transactionForm transaction

40 DepartmentDetailView instance departmentDetailView self

41 DepartmentListView instance departmentListView self

42 DepartmentListView instance departmentListView openWidget

43 departmentsMenuChoiceList clicked DepartmentListView new

44 deptNotNil notNilObject admrDeptIsNil object

45 (deptNotNil,notNilObject --> admrDeptIsNil,object)

value department administrativeDepartment

46 EmployeeDetailView instance employeeDetailView self

47 EmployeeListView instance employeeListView self

48 EmployeeListView instance employeeListView openWidget

49 employeesMenu self containerEmployees menu

50 employeesMenuChoiceList clicked EmployeeListView new

51 employeesMenuChoiceRemove clicked extractor object

52 (employeesMenuChoiceRemove,clicked --> extractor,object)

value containerEmployees selectedItems

53 extractor eachExtractedItem department removeEmployees:

54 (extractor,eachExtractedItem --> department,removeEmployees:)

normalResult containerEmployees refreshAllItems

184 Using VisualAge Smalltalk ObjectExtender

55 hasModifications isTrue concatenator string1

56 hasModifications isFalse concatenator string1

57 hasUnsavedChanges isTrue UnsavedChanges promptFor:

58 hasUnsavedChanges isFalse Window closeWidget

59 (hasUnsavedChanges,isTrue --> UnsavedChanges,promptFor:)

associatedPart Window self

60 mgrReferenceForm referenceDefaultActionRequested

EmployeeDetailView new

Page 211: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 32. Connections of the Rb30DepartmentDetailView (Part 4 of 4)

Source (S) Feature of S Target (T) Feature of T

61 mgrReferenceForm referenceListClicked EmployeeListView new

62 (mgrReferenceForm,referenceDefaultActionRequested --> EmployeeDetailView,new)

normalResult employeeDetailView employeeTmp

63 (mgrReferenceForm,referenceDefaultActionRequested --> EmployeeDetailView,new)

normalResult employeeDetailView openWidget

64 ((mgrReferenceForm,referenceDefaultActionRequested --> EmployeeDetailView,new),normalResult --> employeeDetailView,employeeTmp)

value mgrReferenceForm object

65 pbCancel clicked businessTransaction rollback

66 pbDelete clicked deleteConfirmer prompt

67 pbSave clicked businessTransaction commit

68 pbSave enabled pbCancel enabled

69 (pbSave,clicked --> businessTransaction,commit)

normalResult Window closeWidget

70 pbXInspect clicked Rb30DepartmentDetailView

inspect:

71 (pbXInspect,clicked --> Rb30DepartmentDetailView,inspect:)

parameter1 department self

72 trueElseFalse trueElseFalse deptNoField editable

73 UnsavedChanges noAbort Window closeWidget

74 UnsavedChanges okYesRetry businessTransaction commit

75 (UnsavedChanges,okYesRetry --> normalResult Window closeWidget

Employee and Department Top-Down 185

businessTransaction,commit)

76 Window openedWidget department self

77 Window closeWidgetRequest Rb30DepartmentDetailView

closeWidgetRequested:

78 Window closeWidgetRequest hasUnsavedChanges boolean

79 (Window,closeWidgetRequest --> hasUnsavedChanges,boolean)

value businessTransaction hasModifications

80 (Window,openedWidget --> department,self)

value departmentTmp self

Page 212: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 33. Connections of the Rb30EmployeeDetailView (Part 1 of 3)

Source (S) Feature of S Target (T) Feature of T

1 businessTransaction transaction employee transaction

2 businessTransaction hasModifications pbCancel enabled

3 businessTransaction hasModifications hasModifications boolean

4 concatenator string Window title

5 deleteConfirmer okYesRetry employee remove

6 deleteConfirmer okYesRetry businessTransaction commit

7 (deleteConfirmer,okYesRetry --> businessTransaction,commit)

normalResult Window closeWidget

8 DepartmentDetailView instance departmentDetailView self

9 DepartmentListView instance departmentListView self

10 DepartmentListView instance departmentListView openWidget

11121314

employeeemployeeemployeeemployee

isNotPersistentempNoreferenceStringfirstNme

trueElseFalseempNoFieldconcatenatorfirstNmeField

booleanobjectstring2object

15161718

employeeemployeeemployeeemployee

midInitlastNamephoneNoisPersistent

midInitFieldlastNameFieldphoneNoFieldpbDelete

objectobjectobjectenabled

19202122

employeeemployeeemployeeemployee

jobedLevelhireDatesex

jobFieldedLevelFieldhireDateFieldsexField

objectobjectobjectobject

23 employee bonus bonusField object

186 Using VisualAge Smalltalk ObjectExtender

242526

employeeemployeeemployee

commsalarybirthDate

commFieldsalaryFieldbirthDateField

objectobjectobject

27 hasModifications isTrue concatenator string1

28 hasModifications isFalse concatenator string1

29 hasUnsavedChanges isTrue UnsavedChanges promptFor:

30 hasUnsavedChanges isFalse Window closeWidget

Page 213: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 34. Connections of the Rb30EmployeeDetailView (Part 2 of 3)

Source (S) Feature of S Target (T) Feature of T

31 (hasUnsavedChanges,isTrue --> UnsavedChanges,promptFor:)

associatedPart Window self

32 managedDeptRefForm referenceDefaultActionRequested

DepartmentDetailView new

33 managedDeptRefForm referenceListClicked DepartmentListView new

34 managedDeptRefForm referenceObject employee managedDepartment

35 (managedDeptRefForm,referenceDefaultActionRequested --> DepartmentDetailView,new)

normalResult departmentDetailView modelTmp

36 (managedDeptRefForm,referenceDefaultActionRequested --> DepartmentDetailView,new)

normalResult departmentDetailView openWidget

37 ( (managedDeptRefForm,referenceDefaultActionRequested --> DepartmentDetailView,new),normalResult --> departmentDetailView,modelTmp)

value managedDeptRefForm

object

38 pbCancel clicked businessTransaction rollback

39 pbCancel enabled pbSave enabled

40 pbDelete clicked deleteConfirmer prompt

41 pbSave clicked businessTransaction commit

42 (pbSave,clicked --> businessTransaction,commit)

normalResult Window closeWidget

Employee and Department Top-Down 187

43 pbXInspect clicked Rb30EmployeeDetailView

inspect:

44 (pbXInspect,clicked --> Rb30EmployeeDetailView,inspect:)

parameter1 employee birthDate

45 trueElseFalse trueElseFalse empNoField editable

46 UnsavedChanges noAbort Window closeWidget

Page 214: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 35. Connections of the Rb30EmployeeDetailView (Part 3 of 3)

Source (S) Feature of S Target (T) Feature of T

47 UnsavedChanges okYesRetry businessTransaction

commit

48 (UnsavedChanges,okYesRetry --> businessTransaction,commit)

normalResult Window closeWidget

49 Window openedWidget employee self

50 Window closeWidgetRequest Rb30EmployeeDetailView

closeWidgetRequested:

51 Window closeWidgetRequest hasUnsavedChanges

boolean

52 (Window,closeWidgetRequest --> hasUnsavedChanges,boolean)

value businessTransaction

hasModifications

53 (Window,openedWidget --> employee,self)

value employeeTmp self

54 workDeptRefForm referenceDefaultActionRequested

DepartmentDetailView

new

55 workDeptRefForm referenceListClicked DepartmentListView new

56 workDeptRefForm referenceObject employee workDepartment

57 (workDeptRefForm,referenceDefaultActionRequested --> DepartmentDetailView,new)

normalResult departmentDetailView

modelTmp

58 (workDeptRefForm,referenceDefaultActionRequested --> DepartmentDetailView,new)

normalResult departmentDetailView

openWidget

59 ( value workDeptRefForm object

188 Using VisualAge Smalltalk ObjectExtender

Figure 133 and Figure 134 show the views at runtime with the object setup as described in 7.6.1, “Set up Sample Objects” on page 148.

(workDeptRefForm,referenceDefaultActionRequested --> DepartmentDetailView,new),normalResult --> departmentDetailView,modelTmp)

Page 215: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 133. Rb30Department List and Detail View with Data

Employee and Department Top-Down 189

Figure 134. Rb30Employee List and Detail Views with Data

Page 216: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

If you specified only the Connection type in the Database Connection Info dialog, you can use the GUIs to browse and maintain the Employee and Department tables of the DB2 sample database by specifying Sample as Data source at data store activation time.

Look at the Save and Reset buttons in the detail views in Figure 133 and Figure 134. In the department detail view they are disabled and indicate that no changes have yet been made to the department business object. In the employee detail view they are enabled and indicate that a change has already been made to the employee business object, namely, to the firstNme. Also, the window title shows with the leading asterisk (*) that modifications have already been made to the object. If you close the window, a prompter opens with a message about unsaved changes. The options to continue are:

• Yes—Save the changes and close the window.

• No—Do not save the changes. Discard them and close the window.

• Cancel—Cancel the closing dialog and return to the detail view.

7.7.4 Transaction Save GUIsThe GUIs for the department and employee details (Figure 129 on page 176 and Figure 131 on page 180) are "transaction save". Run the following scenario, and you will understand why and what happens:

1. Open the department list view with all departments (Figure 133 on page 189, left side).

2. Double-click on the S1A department in the list view (Figure 133 on page 189, left side) to open the detail view of the S1A department (Figure 135, left side).

3. Double-click on the S1B department in the list view (Figure 133 on page 189, left side) to open the detail view of the S1B department (Figure 135, right side).

190 Using VisualAge Smalltalk ObjectExtender

4. Select the EMP1A2 employee in the S1A department’s list of employees and drag and drop it onto the S1B department’s list of employees (Figure 135).

5. Look at what happened (Figure 135, left and right side):

• The drag-source object and transaction are still unchanged—the window title is not lead by an asterisk, and the S1A department’s list of employees still shows both employees, EMP1A1 and EMP1A2.

• The drag-target or drop object and transaction have changed—the window title leads with an asterisk, the Save and Reset buttons are

Page 217: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

enabled, and the S1B department’s employee list shows the dropped S1A2 employee.

Figure 135. Department Detail Views after a Drag and Drop of an Employee

Why?

• The dropped event of the list is fired at first and invokes the

Employee and Department Top-Down 191

droppedEmployees: method of the S1B department through the transacted variable. On passing the transacted variable the indirectly through the business transaction connected transaction became the current transaction in which the execution of the addEmployees: method invoked by the droppedEmployees: method (Table 28 on page 179) resulted in a modification to the S1B department.

• The dragCompletedRequest event also fired a method of an object in a transacted variable, but because this draggedEmployees: method is empty, the object and transaction related to the variable remain unchanged. Even if you click on the Refresh button, the same list of S1A department employees appears as before—because the S1B transaction is not yet

Page 218: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

committed. After a save of the S1B transaction the refresh of the S1A window shows one employee less in its list.

Suppose a typical concurrence situation: you opened—before you saved the S1B department—a third department, for example, the S2A department, dragged and dropped the same EMP1A1 employee from the S1A department to the S2A department, and committed the S2A department changes. The attempt to commit the S1B department changes fails—if you declared the workDept foreign key as part of the optimistic predicate. The commit has to fail, because the S2A commit came first—and served first.

To check out the concurrence, open the Map Browser (Figure 136).

192 Using VisualAge Smalltalk ObjectExtender

Figure 136. Map Browser: Defining a Part of the Optimistic Predicate

In the Map Browser select Rb30EmpDeptRb30empdept from the Datastore Maps, select Rb30Employee from the Persistent Classes, select Rb30Employee from the Table Maps, select workDepartment from the Property Maps, and define the workDepartment as part of the optimistic predicate by selecting the Property Maps-> Be part of optimistic predicate from the menu bar. Regenerate the services, and—to see the transaction failure—connect the errorResult of the

Page 219: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

businessTransaction to the prompFor: feature of an error message prompter or the object feature of a message display field that you add to the view.

Employee and Department Top-Down 193

Page 220: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

194 Using VisualAge Smalltalk ObjectExtender

Page 221: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 8. Employee and Department Bottom-Up

The Employee and Department Bottom-Up sample looks at two tables, the Employee and Department tables of the DB2 sample database (Figure 81 on page 105 and Figure 137 on page 195), and goes along the backward or bottom-up development path (see 2.2, “Backward or Bottom-Up: Start with the Database” on page 20 and Figure 11 on page 21). The sample uses the name prefix Rb31, except where parts from the previous sample are reused. The class diagram of the resulting object model looks as shown in Figure 101 on page 127.

Figure 137. DB2 Sample Database: Employee Table with Columns

© Copyright IBM Corp. 1999 195

To exercise this sample, you should have the DB2 sample database created and the DB2 database manager must be started. You can start the DB2 database manager in a system command window with db2start and create the DB2 sample database SAMPLE with db2sampl. The sample database installation uses your userid as the (high-level) qualifier (see also the Note on page 67). If the DB2 sample database is not created or not available, you can use the database and tables created, in 7.4, “Generate Physical Database” on page 145.

Page 222: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

8.1 Import Schema from Relational Database (Metadata)

The import of the schema from the database and the adjustment of the imported schema are similar to the import and adjustment for the single table described in 6.1, “Import Schema from Relational Database (Metadata)” on page 106.

For this sample name the schema Rb31EmpDept and use Rb1EmpDeptSchema for the storage class name and Rb1EmpDeptSchemaApp for the storage application name when saving the schema.

8.1.1 Select Tables and Import SchemaIn the Select Tables dialog (Figure 138), select the Employee and the Department and import the schema.

196 Using VisualAge Smalltalk ObjectExtender

Figure 138. Select Tables Dialog: Select Department and Employee Table

Figure 139 shows the imported Rb31EmpDept schema.

Page 223: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 139. Imported Database Schema Rb31EmpDept

8.1.2 Review and Adjust Imported SchemaBecause the captured tables have no primary key definitions in the database, the tables in the schema have no primary keys defined. In Figure 139, for example, the DEPARTMENT table has no columns marked with the two greater than signs (>>). You have to define the primary keys manually, using the Table Editor (Figure 50 on page 63). The EMPNO column has to be the primary key of the EMPLOYEE table, and the DEPTNO column has to be the primary key of the DEPARTMENT table.

Furthermore, the captured tables have no constraints in the database, so the schema has no foreign key relationships (the list of Foreign Key Relationships in the schema is empty in Figure 139). You have to add them manually in the Foreign Key Relationship Editor (Figure 140).

Employee and Department Bottom-Up 197

Page 224: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 140. Foreign Key Relationship Editor: employee_workDepartment

Choose Foreign Keys->New Foreign Key Relationship... from the menu bar of the Schema Browser and use the information in Figure 141 and Table 36 on page 199 to create the three foreign key relationships.

Figure 141 shows the foreign key relationships that were generated in 7.3, “Generate Schema and Mapping: Metadata and Database” on page 138 to give you an idea of what they should look like, and Table 36 lists them adjusted for this sample.

198 Using VisualAge Smalltalk ObjectExtender

Note: For this sample there is no need to define physical names or to check the Constraints exists in Database box, because we do not have to generate any DDL.

Page 225: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 141. Foreign Key Relationships from Rb30EmpDept Schema

Table 36. Foreign Key Relationships for Rb31EmpDept Schema

Foreign Key Relationship Name

Primary Key Table Foreign Key Table Foreign Key

1 administrativeDepartment_departments

Employee and Department Bottom-Up 199

The last step in preparing for the model and map generation is to prefix the logical table names with Rb31, using the Table Editor, because they will

DEPARTMENT DEPARTMENT ADMRDEPT

2 manager_managedDepartment

EMPLOYEE DEPARTMENT MGRNO

3 workDepartment_employees

DEPARTMENT EMPLOYEE WORKDEPT

Page 226: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

define the model class names. Choose Tables->Edit Tables... to change the logical table names EMPLOYEE and DEPARTMENT to Rb1Employee and Rb31Department, respectively. Figure 142 shows the schema with the changed logical table names and the manually defined foreign key relationships.

Figure 142. Foreign Key Relationships of the Rb31EmpDept Schema

Note: The schema is now ready for the model and map generation, but not yet for the services generation. The last step in preparing for the services

200 Using VisualAge Smalltalk ObjectExtender

generation is to define how column values are converted to their mapped attribute and vice versa, using the Column Editor. Either select a column and click on the Edit button in the Table Editor or double-click on a column in the Schema Browser and select the appropriate converter. For CHAR(nn) columns and String attributes the VapTrimStringConverter fits best with Smalltalk’s String behavior and GUIs: Trailing blanks are trimmed on read and padded on write (see Figure 50 on page 63 and Figure 51 on page 64).

Page 227: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

8.2 Generate Model Definition and Mapping (Metadata)

In 7.1, “Define Model (Metadata)” on page 127 we developed the model for the Employee and the Department by hand. It is open to us to use this model for developing our application and to generate the necessary mappings between the model and the schema by hand too, using the Map Browser. However, to illustrate the power of ObjectExtender, we actually generate the model from the schema that we have just imported and adjusted.

Choose Schemas->Generate Model from Schema from the menu bar in the Schema Browser to generate the model definitions and the mappings. Figure 143 through Figure 146 show the generated model classes and the generated mappings for the Employee and the Department.

Employee and Department Bottom-Up 201

Figure 143. Generated Rb1employee Model Class

Page 228: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 144. Generated Rb31Employee Table Map

202 Using VisualAge Smalltalk ObjectExtender

Figure 145. Generated Rb1department Model Class

Page 229: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 146. Generated Rb31Department Table Map

8.2.1 Review and Adjust the Generated Model DefinitionsNow open the Model Browser and find the new model that has been created. It has been given the same name as the schema, Rb31EmpDept. Note that the relevant class attributes marked with (a) and class associations with corresponding (r) marked class attributes have been generated. (r) stands for relation (that is, a class association).

Note: By default ObjectExtender generates the associations navigable in both directions, the one-to-xxx associations in the direction, where the "one" side is in the left side of the Association Editor window, the "xxx" side (the foreign key side) as Many, and all non-(r) class attributes with Value not required.

Employee and Department Bottom-Up 203

ObjectExtender generated the names for the roles in the associations and the corresponding (r) class attributes. Because they are not particularly meaningful within the context of the application, and because they will become the method names in the future generated model code, we change them, using the Association Editor. In the Model Browser, double-click on either the (r) class attribute or the class association to open the Association Editor and modify the role names. Furthermore, in the Association Editor, adjust the Navigable, Many, and Required box, where required. Use the information in Figure 147 through Figure 149 to edit the class associations. (The easiest way for this sample is to select the Rb1department model class

Page 230: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

in the Model Browser and double-click on each class association. In this way you catch all three class associations of the sample.)

Figure 147. administrativeDepartment_departments Association

204 Using VisualAge Smalltalk ObjectExtender

Figure 148. manager_managedDepartment Association

Page 231: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 149. workDepartment_employees Association

In the Model Editor, double-click on all non-(r) class attributes that which require a value, to open the Class Attribute Error and mark the Value Required check box. Use the information in Table 14 on page 128 and Table 15 on page 129 to determine, which non-(r) class attributes require a value.

The model is now reviewed and adjusted. When we saved the model for the first time, we named the application Rb31EmployeeModelApp and accepted the storage class name of Rb31EmployeeModel.

8.2.2 Review and Adjust the Generated MappingsChanging the names of an (r) class attribute or role name affects the

Employee and Department Bottom-Up 205

mappings by creating mapping errors, indicated by: <<broken: a VapClusterMap >>, <<broken: a VapMapRelationship >>, and <<VapMapValidationError:... (Figure 150 and Figure 151). Fix the broken VapMapRelationships, using the Property Map Editor on the Associations page.

Page 232: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 150. Employee VapValidationErrors <<broken: a VapRelationshipMap >>

206 Using VisualAge Smalltalk ObjectExtender

Figure 151. Department VapValidationErrors <<broken: a VapRelationshipMap >>

In the Map Browser select each persistent class and each table map with a broken cluster map and choose Table Maps->Edit Property Maps... from the menu bar to open the Property Map Editor. Confirm the

Page 233: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Metadata Validation Error message window, select the Associations page, and map the <not mapped> associations to the foreign key relationships. Use the Property Map Editor to fix the broken mappings.

Figure 152. Property Map Editor for Department (see Note below)

Note: When a self-referencing map entry loses focus on either selecting another map or click on the OK button in the Property Map Editor, a post-edit dialog opens (Selection Required dialog in Figure 152) and asks for

Employee and Department Bottom-Up 207

the side of the foreign key relationship for the map that just lost the focus. Therefore the Foreign Key - ADMRDEPT selection in the Selection Required dialog in Figure 152 actually refers to the administrativeDepartment association that was selected and lost focus just before the departments was selected. The side of the foreign key relationship for the departments association is the Primary Key - DEPTNO.

Page 234: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 153. Property Map Editor Open for Employee

Because of the new role names with the new property maps, you must delete the old and broken property maps in the Map Browser. After you delete these old and broken property maps, all mapping errors should disappear. If not, check the mappings again and carefully read the textual summary of the error prone table map and the messages in the Metadata Validation Error window when opening the Map Property Editor.

Figure 154 shows the adjusted Rb31Department table map. Look at the textual summary of the self-referencing relationship maps in the lower half of the Map Browser window:

• Rb31department, 1:1, administrativeDepartment, forward map, #member • Rb31department, 0:’many’, departments, backward map, #parent

The data store map is now reviewed and adjusted. When we save the map, we give the associated application the name Rb31EmpDeptMapApp and accept

208 Using VisualAge Smalltalk ObjectExtender

the offered storage class name of Rb31EmpDeptRb31empdeptMap.

Page 235: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Employee and Department Bottom-Up 209

Figure 154. Adjusted Rb31Department Table Map

8.3 Generate Model Code Classes

To generate the model code classes from the metadata, in previous examples, in the Model Browser, select Models->Model Code Generation Options from the menu bar to define model code application (Figure 155), and then Models->Generate to actually generate the model code classes from the metadata.

Page 236: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 155. Model Code Generation Options for Rb31EmpDept Model

You can inspect the generated classes with the VisualAge Organizer. The relevant classes are defined in the Rb31EmpDeptApp.

8.4 Generate Service Classes

Once the model code classes have been generated, we generate the service classes to support the physical database access. As in the previous examples, we use the Map Browser for this. The first stage is to ensure that the generation options have been set to establish a connection to the database. In the Map Browser choose Datastore Maps->Generation Options... to open the generation options dialog. A typical dialog is shown in Figure 89 on page 112 and Figure 91 on page 113. For the services application we accept ObjectExtender’s model and map dependent default name: Rb31EmpDeptRb31empdeptServicesApp.

In the Map Browser we then choose Datastore Maps->Generate Services to generate the service classes. You can inspect the generated service classes

210 Using VisualAge Smalltalk ObjectExtender

with the VisualAge Organizer. The relevant classes are defined in the Rb31EmpDeptRb31empdeptServicesApp.

Note that the data store has the name Rb31EmpDeptRb31empdeptDataStore and can be activated by executing the following Smalltalk expression:

Rb31EmpDeptRb31empdeptDataStore singleton activate

Page 237: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

8.5 Run Sample Headless with Scripts

We now test our code by running headless, without a user interface. We follow the general approach used in the previous samples. In this case, as we are using an existing database, we check only that we can access data and navigate the links.

8.5.1 Accessing the Data in the DatabaseHaving activated the data store, using the ObjectExtender Status Browser, we test that we can read data from the database. You can use the scripts listed below to do this and use the Inspector to look at the retrieved objects. Execute the following script to look at the name of the employee with employee number 000240:

| emp |emp := Rb31employeeHome singleton findByEmpno: ’000240’.emp lastname inspect"---> ’MARINO ’ is inspected"

Note that the leading zeros are required for the employee number because this attribute is a string and not a number. So ’000240’ is not the same as ’240’.

Execute the following script to look at the name of the department with department number A00:

| dept |dept := Rb31departmentHome singleton findByDeptno: ’A00’.dept deptname inspect."---> ’SPIFFY COMPUTER SERVICE DIV.’ is inspected"

If you use a separate DB2 command window to inspect the actual contents of the database, you can confirm that the results retrieved by our scripts agree with the values in the database.

Employee and Department Bottom-Up 211

8.5.2 Navigating the Object LinksNext we confirm that we can navigate all links in all directions. The test cases are described in detail in 7.6.2, “Navigate the Objects” on page 154. The scripts and results are summarized below.

Finding the Employees of a DepartmentExecuting the following script opens an Inspector window as shown in Figure 156 and tells us that there are three employees in the department with deptno A00:

Page 238: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

| dept emps |dept := Rb31departmentHome singleton findByDeptno: ’A00’.emps := dept employees asOrderedCollection asSortedCollection: [ :a :b |

a empno < b empno ].emps inspect

Figure 156. Employees of Department A00

Finding an Employee’s DepartmentExecuting the following script opens an Inspector window as shown in Figure 158 and tells us that the employee with empno 000170 works in department with deptno D11:

| emp |emp := Rb31employeeHome singleton findByEmpno: ’000170’.emp workDepartment inspect

212 Using VisualAge Smalltalk ObjectExtender

Figure 157. Department D11 of Employee 000170

Page 239: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Finding the Manager of a DepartmentExecuting the following script opens the Inspector window as shown in Figure 158 and tells us, that the employee with empno 00010 is the manager of the department with deptno A00:

| dept |dept := Rb31departmentHome singleton findByDeptno: ’A00’.dept manager inspect

Figure 158. Manager (Employee) 000010 of Department A00

Executing the same script for the department with deptno D01, which has no manager, delivers the expected nil result:

| dept |dept := Rb31departmentHome singleton findByDeptno: ’D01’.dept manager inspect"---> nil"

Determining Whether an Employee Manages a DepartmentFirst we test the employee with empno 000010 who is known to manage the department with deptno A00 (last in text pane in Figure 158 and Figure 159, ...’A00’...’000010’... and ...’A00’ ’000010’...) with the following script:

| emp |emp := Rb31employeeHome singleton findByEmpno: ’000010’.

Employee and Department Bottom-Up 213

emp managedDepartment inspect

Figure 159. Managed Department of Employee (Manager) 000010

Page 240: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Now we test for an employee who is known not to manage a department, employee with empno 000170. Not surprisingly, the debugger fires up with the error message “No object found,” as seen when we tried the same test in 7.6.2, “Navigate the Objects” on page 154. The debugger display is to all intents and purposes the same as that seen in Figure 224 on page 394.

The reasons for the problem and one solution are the same as detailed in Appendix F.4.2, “Backward: Individual Access Solution (Overriding)” on page 394. We could indeed use the approach we used there, but by now warning bells should be ringing. This is the second time that this problem has occurred. We should be looking for a generic solution rather than patching the relevant relationship class each time we find this problem. The implementation of a more generic solution is discussed in more detail in the Appendix F.4.3, “Backward: Generic Access Solution (New Inheritance)” on page 396.

8.6 Run Sample with User Interface

In Chapter 5, “Employee Top-Down” on page 47, we generated a user interface to manage the employee. Here, we present a single window user interface to manage the departments. Again, the user interface we present here is simple. It contains no business rules and no error handling.

The developed user interface to manage departments—CRUD (create, read, update, and delete) departments and assign departments, employees, and managers—is shown in Figure 160. Figure 162 on page 223 shows the parts list. The connection details are shown in Table 45 on page 224 through Table 47 on page 226. Figure 161 on page 217 shows the user interface at runtime.

To simplify the user interface for this sample, we add new public interface attributes and new methods to the Rb31department and Rb31employee classes:

214 Using VisualAge Smalltalk ObjectExtender

• Single reference string attributes and methods to access and reasonably display the required fields of the associated classes (see pages 218 trough 219)

• Signalling multiple reference attributes and methods to update the view lists of departments and employees (see page 220)

• Customized add... and remove... methods for adding and removing departments and signalling the changes (see pages 221 through 222)

Page 241: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Employee and Department Bottom-Up 215

Figure 160. Rb31DeptView to Manage Departments in the Composition Editor

Page 242: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The implementation key features of the user interface in Figure 160 are:

• A container to hold a list of all departments.

• A container labeled employees to hold a list of departments in the new or selected department. The items attribute is connected to the departments attribute of the department.

• A container labeled other employees to hold list of the other employees, that are the employees which are not in the new or selected department.

• A button labeled "<<" to move selected departments from the list of the other departments into the list of employees of the new or selected department.

• A button labeled ">>" to remove selected departments from the list of the new or selected department.

• A container labeled employees to hold a list of employees in the new or selected department. The items attribute is connected to the employee attribute of the department.

• A container labeled other employees to hold list of the other employees, that are the employees which are not in the new or selected department.

• A button labeled "<<" to move selected employees from the list of available employees into the list of employees of the new or selected department.

• A button labeled ">>" to remove selected employees from the list employees of the new or selected department.

• A button labeled Mgr to make the selected employee the manager of the new or selected department. The button is enabled only when an employee of the new or selected department is selected. If more than one employee is selected, the first is taken.

216 Using VisualAge Smalltalk ObjectExtender

Page 243: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Employee and Department Bottom-Up 217

Figure 161. Rb31DeptView at Runtime to Manage Departments at Runtime

Page 244: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

For single references in the department, we add the new public interface attributes and methods deptNoAndName, managerEmpNoAndName, and admrDeptNoAndName to the Rb31department class (Table 37 and Table 38).

Table 37. Reference Attributes in the Rb31department Public Interface

Table 38. Reference Methods of Rb31department

Attribute name Get selector Attribute data type

1 admrDeptNoAndName admrDeptNoAndName String

2 deptNoAndName deptNoAndName String

3 managerEmpNoAndName managerEmpNoAndName String

Rb31department>>#methods in category OERedbook

1 admrDeptNoAndName

"Return the value of admrDeptNoAndName."

^self administrativeDepartment deptNoAndName

2 deptNoAndName

"Return the value of deptNoAndName."

| tDeptno tDeptname |

(tDeptno := self deptno) == nil ifTrue: [tDeptno := ’’].(tDeptname := self deptname) == nil ifTrue: [tDeptname := ’’].^ tDeptno , ’ ’ , tDeptname

3 managerEmpNoAndName

"Return the value of managerEmpNoAndName."

218 Using VisualAge Smalltalk ObjectExtender

| mgr |^(mgr := self manager) ~~ nil

ifTrue: [mgr empNoAndName]ifFalse: [’-’]

Page 245: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

For single references in the employee, we add the new public interface attributes and methods empNoAndName, managerEmpnoAndName, and workDeptNoAndName to the Rb31employee class (Table 39 and Table 40).

Table 39. Reference Attributes in the Rb31employee Public Interface

Table 40. Reference Methods of Rb31employee

Attribute name Get selector Attribute data type

1 deptNoAndName deptNoAndName String

2 managerEmpNoAndName managerEmpNoAndName String

3 workDeptNoAndName workDeptNoAndName String

Rb31employee>>#methods (for reference) in category OERedbook

1 empNoAndName

"Return the value of empNoAndName."

| stream |(stream := WriteStream on: String new)

nextPutAll: self empno; nextPut: $ ;nextPutAll: self lastname trimBlanks; nextPutAll: ’, ’;nextPutAll: self firstnme trimBlanks.

self midinit asString trimBlanks notEmpty ifTrue: [stream nextPutAll: ' ('; nextPut: self midinit; nextPutAll: ’.)’ ].

^stream contents

2 managerEmpNoAndName

"Return the value of managerEmpNoAndName."

| dept |^(dept := self workDepartment) ~~ nil

ifTrue: [dept managerEmpNoAndName]

Employee and Department Bottom-Up 219

ifFalse: ['-']

3 workDeptNoAndName

"Return the value of workDeptNoAndName."

| dept |^(dept := self workDepartment) ~~ nil

ifTrue: [dept deptNoAndName]ifFalse: ['-']

Page 246: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

For adding and removing departments and employees, the Rb31Department class needs additional public interface attributes and methods (Table 41 and Table 42), and user code in the add... and remove... methods (Table 43 on page 221 and Table 44 on page 222).

Table 41. Signalled Attributes in the Rb31department Public Interface

Table 42. Signalled Methods in the Rb31department Class

Attribute name Get selector /Change event symbol

Attribute data type /Contents type

1 sDepartments sDepartments /sDepartments

LinkCollectionShell /Rb31departments

2 sEmployees sEmployees /sEmployees

LinkCollectionShell /Rb31employee

Note: s-prefix stands for signalled (for example: signaledDepartements)

Rb31employee>>#methods (for singals) in category OERedbook

1 sDepartments

"Signalled departments."

^self departments

2 sEmployees

"Signalled employees."

^self employees

220 Using VisualAge Smalltalk ObjectExtender

Page 247: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 43. Add.../Remove... Departments Methods in Rb31department Class

Rb31department>>#methods (add.../remove... departments)in category OERedbook-customized

1

>>>>>

addDepartments: aDepartments

"Add method forwarded to the link collection"

"Begin user code {pre-Connect}"(aDepartments isKindOf: Collection) ifTrue: [

aDepartments do: [ :e | self addDepartments: e ].self signalEvent: #sDepartments

with: self departments.^aDepartments ].

"End user code"

self departmentsLink connectTo: aDepartments.

"Begin user code {post-Connect}""End user code"

2

>>>>>>>

removeDepartments: aDepartments

"Remove method forwarded to the link collection"

"Begin user code {pre-Disconnect}"(aDepartments isKindOf: Collection) ifTrue: [

aDepartments do: [ :e |self removeDepartments: e.e administrativeDepartment: e ].

self signalEvent: #sDepartments with: self departments.

^aDepartments ]."End user code"

self departmentsLink disconnectFrom: aDepartments.

Employee and Department Bottom-Up 221

"Begin user code {post-Connect}""End user code"

Page 248: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 44. Add.../Remove... Employees Methods in Rb31department Class

Rb31department>>#methods (add.../remove... departments)in category OERedbook-customized

1

>>>>>

addEmployees: anEmployees

"Add method forwarded to the link collection"

"Begin user code {pre-Connect}"(anEmployees isKindOf: Collection) ifTrue: [

anEmployees do: [ :e | self addEmployees: e ].self signalEvent: #sEmployees

with: self employees.^anEmployees ].

"End user code"

self employeesLink connectTo: anEmployees.

"Begin user code {post-Connect}""End user code"

2

>>>>>>>

removeEmployees: anEmployees

"Remove method forwarded to the link collection"

"Begin user code {pre-Disconnect}"(anEmployees isKindOf: Collection) ifTrue: [

anEmployees do: [ :e |self removeEmployees: e.e workDepartment: nil ].

self signalEvent: #sEmployees with: self employees.

^anEmployees ]."End user code"

self employeesLink disconnectFrom: anEmployees.

222 Using VisualAge Smalltalk ObjectExtender

"Begin user code {post-Connect}""End user code"

Page 249: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Employee and Department Bottom-Up 223

Figure 162. Rb31DeptView Parts List

Page 250: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 45. Connections of Rb31DeptView (Part 1 of 3)

Source (S) Feature of S Target (T) Feature of T

1 contDepartmentsList selectedItem department self

23

copier1(copier1,copy --> availableDs,self)

copynormalResult

otherDepartmentsotherDepartments

selfremoveAll:

4 ( (copier1,copy --> availableDs,self),normalResult --> availableDs,removeAll:)

aCollection department departments

56

copier2(copier2,copy --> availableEs,self)

copynormalResult

otherEmployeesotherEmployees

selfremoveAll:

7 ( (copier2,copy --> availableEs,self),normalResult --> availableEs,removeAll:)

aCollection department employees

89

1011

departmentdepartmentdepartmentdepartment

sDepartmentssEmployeesdeptnamedeptno

departmentsemployeesdeptnameFielddeptnoField

itemsitemsobjectobject

1213141516

departmentdepartmentdepartmentdepartmentdepartment

locationisNotPersistentmanagersEmployeessDepartments

locationFielddeptnoFieldmanagerFieldcopier2copier1

objectenabledobjectoriginorigin

17 (department,manager --> managerField,object)

value department managerEmpNoAndName

18 (department,sDepartments --> copier1,origin)

value allDepartments self

19 (department,sEmployees --> copier2,origin)

value allEmployees self

224 Using VisualAge Smalltalk ObjectExtender

202122

departmentsemployeesemployees

selectionIsValidselectionIsValidselectionIsValid

pbRemoveDeptspbRemoveEmpspbSetManager

enabledenabledenabled

23242526

otherDepartmentsotherDeptsotherEmployeesotherEmps

selfselectionIsValidselfselectionIsValid

otherDeptspbAddDeptsotherEmpspbAddEmps

itemsenableditemsenabled

Page 251: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 46. Connections of Rb31DeptView (Part 2 of 3)

Source (S) Feature of S Target (T) Feature of T

27 pbAddDepts clicked department addDepartments:

28 (pbAddDepts,clicked --> department,addDepartments:)

aDepartments otherDepts selectedItems

29 pbAddEmps clicked department addEmployees:

30 (pbAddEmps,clicked --> department,addEmployees:)

anEmployees otherEmps selectedItems

313233

pbCancelpbMarkDeletepbNew

clickedclickedclicked

topLevelTransactiondepartmentdepartmentHome

rollbackremovecreate

34 (pbNew,clicked --> departmentHome,create)

normalResult department self

35 ( (pbNew,clicked --> departmentHome,create),normalResult --> department,self)

normalResult department administrativeDepartment

36 ( ( (pbNew,clicked --> departmentHome,create),normalResult --> department,self),normalResult --> department,administrativeDepartment)

value department self

37 pbRemoveDepts clicked department removeDepartments:

38 (pbRemoveDepts,clicked --> department,removeDepartments:)

aDepartments departments selectedItems

39 pbRemoveEmps clicked department removeEmployees:

Employee and Department Bottom-Up 225

40 (pbRemoveEmps,clicked --> department,removeEmployees:)

anEmployees employees selectedItems

4142

pbSavepbSetManager

clickedclicked

topLevelTransactiondepartment

commitmanager

43 (pbSetManager,clicked --> department,manager)

value employees selectedItem

Page 252: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 47. Connections of Rb31DeptView (Part 3 of 3)

Source (S) Feature of S Target (T) Feature of T

44454647

topLevelTransactiontopLevelTransactiontopLevelTransactiontopLevelTransaction

selfselfselfself

departmentallEmployeescontDepartmentsListallDepartments

transactionselfitemsself

48 topLevelTransaction commitedOrRolledback

sharedTransaction beginChild

49 (topLevelTransaction,committedOrRolledback --> sharedTransaction,beginChild)

normalResult topLevelTransaction self

50 (topLevelTransaction,self --> allDepartments,self)

value departmentHome allInstances

51 (topLevelTransaction,self --> allEmployees,self)

value employeeHome allInstances

52 (topLevelTransaction,self --> contDepartmentsList,items)

value departmentHome allInstances

53 Window aboutToOpenWidget

sharedTransaction beginChild

54 (Window,aboutToOpenWidget --> sharedTransaction,beginChild)

normalResult topLevelTransaction self

226 Using VisualAge Smalltalk ObjectExtender

Page 253: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 9. Employee and Department - Outside-In

For the sample going along the Outside-In development path we look at the Employee and Department classes. Figure 101 on page 127 shows the class diagram. The crucial task along the path is mapping the model to the schema. This sample uses the Rb32 prefix.

9.1 Preparation Work

Before we can start with the mapping task, we need a model (actually a metamodel) with the Employee and Department classes and their associations, and a schema of the Employee and Department database tables and their primary key and foreign key associations.

You define the model by the metamodel in the same way as described in 7.1, “Define Model (Metadata)” on page 127, or you reuse the model created there. For the schema you either define it manually, import it from the database tables as described in 8.1, “Import Schema from Relational Database (Metadata)” on page 196, or reuse the schema created there.

There is nothing wrong and nothing will go wrong with reusing the model, the schema, or both. The data store, which is generated together with the services from the map, and the data store’s activation at runtime ensure the proper working of the sample. If you reuse the model, you do not even have to generate or regenerate the model code classes, and, furthermore, you can run the same tests scripts and GUI applications used in Chapter 7, “Employee and Department Top-Down” on page 127 (with the proper data store activation).

9.2 Create the Map

In the Map Browser choose Datastore Maps->New Datastore Map... from

© Copyright IBM Corp. 1999 227

the menu bar. In the New Datastore Map dialog window (Figure 163) enter Name, Model, and Schema from the information listed in Table 48 on page 228.

Note: In this sample we reuse the Rb30Model from Chapter 7, “Employee and Department Top-Down” on page 127 and Rb31Schema from Chapter 8, “Employee and Department Bottom-Up” on page 195.

Page 254: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 163. New Datastore Map Dialog

Table 48. Map Creation Information

Item Entry Remark

Name Rb32EmpDeptRb32EmpDept Use this data store map if you created a dedicated model and schema.

Rb30EmpDeptRb31EmpDept Use this data store map if you decided to reuse the existing model and schema.

Model Rb32EmpDept Use this model if you created it for this sample.

Rb30EmpDept Use this model if you decided to reuse the existing model.

Schema Rb32EmpDept Use this schema if you created it for this sample.

Rb31EmpDept Use this schema if you decided to

228 Using VisualAge Smalltalk ObjectExtender

9.3 Create Table Maps

In the Map Browser (Figure 164) select the newly created, empty data store map and a persistent class. Then choose New Table Map-> Add Cluster Map with no inheritance... from either Table Maps on the

reuse the existing model.

Note: It is useful to compose the data store Name from the model name and the schema name, for example, Rb30EmpDeptRb31EmpDept.

Page 255: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

menu bar or the pop-up menu of the Table Maps list. In the Table Map With... dialog select the table, for which you want to define mappings.

Create table maps for the Rb30Department and Rb30Employee persistent classes with the Rb31Department and Rb31Employee tables.

Figure 164. Table Map Creation Dialog

9.4 Map Attributes to Columns

In the Map Browser select a table map and choose Table Maps-> Edit Property Maps to open the Property Map Editor (Figure 165). The Property Map Editor opens on the Attributes page. Map each model attribute to a table column with a Simple mapping. Open the Property Map Editor on the each table map and perform the Class Attribute to Table Column mappings.

Employee and Department - Outside-In 229

Note: An incorrect mapping, such as mapping more than one class attribute to one table column or mapping incompatible column definitions, results in a <<broken: a VapClusterMap >> in the Table Maps list of the Map Browser. Open the Property Map Editor on that broken map and correct the mapping. Opening a broken map displays a detailed Metadata Validation Error message, which you can use as an aid to correct the error (Figure 166).

Page 256: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 165. Property Map Editor with Map Types and Table Columns

Figure 166. Metadata Validation Error: Column Overlap

9.5 Map Associations to Foreign Key Relationships

230 Using VisualAge Smalltalk ObjectExtender

On the Associations page in the Property Map Editor (Figure 167), perform the Class Association to Foreign Key Relationship mappings. For self-referencing associations, see Figure 152 on page 207.

Save the data store map. For the storage application name use the map name with the MapApp suffix, and for the storage class name, use the map name with the Map suffix.

Page 257: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 167. Associations Property Map Editor

9.6 Generate the Services

Before you generate the services check the generation options. The data source of the database connection specification is the DB2 sample database, because we reuse the schema that was imported from there in 8.1, “Import Schema from Relational Database (Metadata)” on page 196. For the services application, accept the default name.

After generating the services apply the fixes for the nil-able, non-required one-to-one departmentToManager association as described in Appendix F.4, “Non-Required, One-to-Xxx Association” on page 392.

Note: The services generation may use the map to correct the generated model code for backward relationships, because the model code generation

Employee and Department - Outside-In 231

assumes all one-to-one relationships as forwards. If the model code application is not an open edition, you are asked whether ObjectExtender should create a scratch edition. But in this sample model code changes are required by the fact, that the sample, from where the model and model code is reused, has constraints defined in the database, whereas the sample, from where the schema and database is reused, has no constraints in the database.

Page 258: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

9.7 Run the Sample

Because we reuse the Rb30EmpDept model from 7.1, “Define Model (Metadata)” on page 127, we can also reuse the scripts and the drag-drop supporting GUIs from the same chapter, namely 7.6, “Run Sample Headless with Scripts” on page 146, and 7.7, “Run Sample with User Interface” on page 161 by activating the correct data store, namely Rb30EmpDeptRb31EmpDeptDataStore. Figure 168 shows an a tree view as a GUI alternative. The view is a read-only view. Table 49 on page 233 and Table 50 on page 234 list the scripts to supply the items (roots), the children, and the visual information. Table 51 on page 235 lists the connections.

Note: The workDepartment of the employee entry with empNo 000130 was set to nil by setting the workDept column value in the database to NULL.

232 Using VisualAge Smalltalk ObjectExtender

Figure 168. Rb30EmpDeptRb31EmpDeptTreeView

Page 259: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 49. Rb30EmpDeptRb31EmpDeptTreeView Scripts (Part 1 of 2)

Rb30EmpDeptRb31EmpDeptTreeView>>#methods (root(s).../children...)

1 rootsFrom: departments and: employees

"Return the root/ top department(s) and employees."

^( departments select: [ :e |e administrativeDepartment = e ] ), ( employees select: [ :e |

e workDepartment == nil ] )

2 childrenRequested: requestData

"Set the requestData’s children."

| item children child |

(item := requestData item) class name == #Rb30Department ifTrue: [(children := OrderedCollection new)

addAll: ( item departments asOrderedCollectionremove: item ifAbsent: [];yourself ).

(tbManager selection and: [(child := item manager) notNil ]) ifTrue: [children add: child ].

tbEmployees selection ifTrue: [children

addAll: (item employees asOrderedCollectionremove: item manager ifAbsent: [];yourself ) ] ] ifFalse: [

^nil].

requestDatachildren: children

Employee and Department - Outside-In 233

Page 260: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 50. Rb30EmpDeptRb31EmpDeptTreeView Scripts (Part 2 of 2)

Rb30EmpDeptRb31EmpDeptTreeView>>#visualInfoRequested: method

3 visualInfoRequested: requestData

"Set the requestData’s visual information, such as icon, label, hasChildren."

| item icon label hasChildren |

icon := requestData icon.(item := requestData item)

item class name == #Rb30Department ifTrue: [icon :=AbtIconDescriptor new

moduleName: ’abticons’; id: 106;icon.

label := (WriteStream on: String new) nextPutAll: item referenceString; nextPutAll: ’ - ’ ;nextPutAll: item managerReferenceString;contents.

hasChildren := (item departments notEmptyor: [ item manager notNilor: [item employees notEmpty] ]) ] ifFalse: [

item class name == #Rb30Employee ifTrue: [item managedDepartment == nil ifTrue: [

icon := AbtIconDescriptor newmoduleName: ’abticons’; id: 543;icon ].

label := (WriteStream on: String new)nextPutAll: item referenceString; nextPutAll: ’ - ’ ;nextPutAll: item phoneNo; nextPutAll: ’ - ’;nextPutAll: item job;contents.

hasChildren := false ] ifFalse: [

234 Using VisualAge Smalltalk ObjectExtender

^nil ] ].

requestDataicon: icon;label: label;hasChildren: hasChildren

Page 261: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 51. Connections of Rb30EmpDeptRb31EmpDeptTreeView

Source (S) Feature of S Target (T) Feature of T

1 contIconTree visualInfoRequested

Rb30EmpDeptRb31EmpDeptTreeView

visualInfoRequested:

2 contIconTree itemChildrenRequested

Rb30EmpDeptRb31EmpDeptTreeView

childrenRequested:

3 departmentHome self departmenHomeT self

4 employeeHome self employeeHomeT self

5 topLevelTransaction committedOrRolledback

sharedTransaction beginChild

6 topLevelTransaction self departmenHomeT transaction

7 topLevelTransaction self employeeHomeT transaction

8 topLevelTransaction self Rb30EmpDeptRb31EmpDeptTreeView

rootsFrom:and:

9 (topLevelTransaction,committedOrRolledback --> sharedTransaction,beginChild)

normalResult topLevelTransaction self

10 (topLevelTransaction,self --> Rb30EmpDeptRb31EmpDeptTreeView,rootsFrom:and:)

normalResult contIconTree items

11 (topLevelTransaction,self --> Rb30EmpDeptRb31EmpDeptTreeView,rootsFrom:and:)

parameter1 departmenHomeT allInstances

12 (topLevelTransaction,self --> Rb30EmpDeptRb31EmpDeptTreeView,rootsFrom:and:)

parameter2 employeeHomeT allInstances

13 Window aboutToOpenWidget

sharedTransaction beginChild

Employee and Department - Outside-In 235

14 (Window,aboutToOpenWidget --> sharedTransaction,beginChild)

normalResult topLevelTransaction self

Page 262: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

236 Using VisualAge Smalltalk ObjectExtender

Page 263: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 10. Summary and Conclusion

In Part 2, “Your First Samples” on page 45, we looked at a number of simple examples, working them forward from the model and backward from a legacy database. Each of the samples demonstrates some interesting features of ObjectExtender. It is also possible to have a middle solution, where we produce a new model and map it to an existing database.

The important features demonstrated in Chapter 5, “Employee Top-Down” on page 47, through Chapter 9, “Employee and Department - Outside-In” on page 227, are these:

• You must decide on the approach to be used for building the system. Do you want to develop the database from scratch or do you want to use an existing database? ObjectExtender supports a true mix-and- match approach where it is possible to start at either end or to take the middle way.

• ObjectExtender’s code generation services are very powerful but they cannot envisage all possible user cases and all possible circumstances. There is a need to be careful where there are potential circular paths in the class diagram. Some user coding will be required in all but the simplest cases.

• It is important to check the results of generation and testing. We found some problems only because we checked both sets of results.

• Testing headless, without a user interface, provides a simple method of testing and allows the testing of cases that the user interface cannot explore.

• ObjectExtender supports multiple data store and services implementations for one and the same model. Activating the data store determines which data store and services implementations are connected to the model. The home of the model is the logical connection to the

© Copyright IBM Corp. 1999 237

activated data store and services.

• It is necessary to consider adding validation, error handling, and business rules.

• Object identifiers are almost sacrosanct. Once created, they should not be changed.

• When working back from an existing database design, consider carefully whether you want to use the names of the existing tables, columns, and foreign keys as logical names. Your implementation is likely to be easier to

Page 264: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

maintain if you choose logical names that are more meaningful than those compressed to fit into some arbitrary database limit.

• Do not be afraid to implement additional methods for the generated classes if it makes your user interface design easier. It is much easier to write a small selector for a class to deliver a composite attribute (for example, employee number and last name) than it is to try and code it visually or into a script in the user interface.

238 Using VisualAge Smalltalk ObjectExtender

Page 265: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Part 3. Advanced Details

© Copyright IBM Corp. 1999 239

Page 266: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

240 Using VisualAge Smalltalk ObjectExtender

Page 267: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 11. Many-to-Many Associations

In the Library Management System, there is an association that has a many-to-many cardinality: namely, that between Title and Category (Figure 169). A title can belong to one or more categories, and a category can consist of any number of titles.

Figure 169. Library Management System: Title and Category Analysis View

11.1 Define the Model

With the current ObjectExtender implementation, we construct a many-to-many relationship by joining together two one-to-many relationships. Consequently, we need an additional association class that has a one-to-many relationship to each of the classes. Figure 170 shows the resulting design model.

© Copyright IBM Corp. 1999 241

Figure 170. Library Management System: Title and Category Design View

Page 268: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Each instance of the newly introduced TitleToCategory association class represents a connection from exactly one Title object to exactly one Category object. This lays the foundation of the model to specify in ObjectExtender’s Model Browser.

The first step is to enter the Title and Category classes with the attribute specifications in Table 52.

Table 52. Rb50Title and Rb50Category Attributes

The next step is to create the association class TitleToCategory, without entering any attributes. As soon as we have created the class, we can specify the one-to-many relationships. The convention used here for naming these relationships is that the association class name is abbreviated to the first letters of the classes it connects. Thus, the association between TitleToCategory and Title is called tcToTitle (Figure 171).

At first glance, the multiplicity of settings may be a bit confusing. The cardinality on the side of the business class (here, Title) is always exactly one (the Required checkbox is selected but the Many checkbox is not). The cardinality on the side of the association class always conforms to that of the cardinality on the business-class end of the many-to-many relationship in the analysis model. In this case, it is one or more (both Many and Required are

Class Name Attribute Name Attribute Type Required

Rb50Title isbnNumber String Yes (Object Id)

author String No

publisher String No

description String No

Rb50Category id String Yes (Object Id)

name String No

242 Using VisualAge Smalltalk ObjectExtender

selected). Note that we chose to call the role of TitleToCategory in this association categoryAssociations, to reflect the fact that a Title has a collection of associations to Category, not a set of direct references to Category objects.

In the same manner, the second one-to-many association between TitleToCategory and Category is defined. It is called tcToCategory (Figure 172).

Page 269: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 171. Association between Title and TitleToCategory

Many-to-Many Associations 243

Figure 172. Association between TitleToCategory and Category

Page 270: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Because no object ID attributes have been added to TitleToCategory yet, the last step in the definition of the model is to use the association roles for that purpose in the Class Editor (Figure 173).

Figure 173. Rb50TitleToCategory Class

11.2 Define Schema and Mapping

When the model is completed, one option is to Generate schema from model in the Model Browser. Because of DB2 naming limitations (maximum length of 18 characters, no spaces), however, the generated schema would need to be worked over manually. (For details about DB2 naming limitations, see 12.1.2, “Define the Schema” on page 260.) Therefore, we elected to start from scratch with a new schema. Figure 52 shows the relevant table definitions.

244 Using VisualAge Smalltalk ObjectExtender

The next step is to define the foreign key relationships from Rb50Title2Category to Rb50Title and Rb50Category. Figure 174 shows the result is shown for one of the relationships (Rb50TitleToCategory to Rb50Category).

Once the schema is completed, the mapping is straightforward, as is the generation of the model and service code.

Page 271: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 53. Rb50Title, Rb50Category, and Rb50TitleToCategory Tables

Table Column Type

Rb50Title isbnNumber VARCHAR(12) NOT NULL

author VARCHAR(50)

publisher VARCHAR(50)

description VARCHAR(256)

Rb50Category id VARCHAR(12) NOT NULL

name VARCHAR(50)

Rb50Title2Category title VARCHAR(12) NOT NULL

category VARCHAR(12) NOT NULL

Many-to-Many Associations 245

Figure 174. Rb50 Title2Category to Rb50Category Foreign Key Relationship

Page 272: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

11.3 Test Sample

Once all necessary code is generated, we can test the model with a sample application. Again, we do this in two steps. First, we test headless with simple scripts, and then we test with a GUI. The complete scripts are in the Rb50TstW.wsp workspace file (see Appendix C, “Downloadables, ConfigMaps, Applications” on page 355).

11.3.1 Run Sample Headless with ScriptsSuppose that we have to implement the part of the Library Management System that enables the user to enter new titles, edit and delete existing titles, and assign categories to them. We cover all these steps in the next sections, but categories must already be present.

We use a simple script here to populate the Category table with categories that are not interrelated:

"Setup categories."Transaction begin.(Rb50CategoryHome singleton createForId: ’1’) name: ’Philosophy’.(Rb50CategoryHome singleton createForId: ’2’) name: ’Computer Science’.(Rb50CategoryHome singleton createForId: ’3’) name: ’History’.(Rb50CategoryHome singleton createForId: ’4’) name: ’Art’.Transaction current commit.

To populate the Title table with titles we use this script:

"Setup titles."Transaction begin.(Rb50TitleHome singleton createForIsbnNumber: ’123456789’)

description: ’My IBM’; author: ’Watson’; publisher: ’IBM’.(Rb50TitleHome singleton createForIsbnNumber: ’98765431’)

description: ’IBM as Supplier’; author: ’Customer’; publisher: ’Unknown’.

246 Using VisualAge Smalltalk ObjectExtender

Transaction current commit.

There is nothing special about these scripts; you can extend them as you like.

11.3.2 Hiding Implementation DetailsOne of the key ideas of object orientation is to separate interface from implementation. Without having to know what is going on behind the scenes, a user should be able to use a class by just adhering to its protocol. Similarly,

Page 273: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

we do not want the users of Title or Category to worry about the TitleToCategory class.That is our job as implementers of these classes.

ObjectExtender automatically generates instance methods in Title and Category for accessing and managing the links to TitleToCategory objects. For Title, ObjectExtender generated the categoryAssociations, addCategoryAssociations, and removeCategoryAssociations methods, according to the name we gave the role of the class in the association specification in the Model Browser. But ObjectExtender cannot generate methods to directly access Categories from Title because, unfortunately, it cannot guess our intentions. So we have to add the categories, addCategory, and removeCategory methods to Title, making the TitleToCategory objects in between transparent to the users of Title. We could do the same for Category, but for the purpose of this example the extension of Title is sufficient.

Returning the title’s categories is straightforward: We simply iterate through the collection of TitleToCategory objects in Title and return the Categories from there. To make this method accessible in the VisualAge Composition Editor, too, we have to define the attribute categories, with categories as get selector and change event symbol, in the Public Interface Editor for Title. (For a more efficient implementation we would use a CategoryHome>>#findForTitle: method with a selective join SQL in the shared transaction context. Note that the current transaction must be saved for the find and resumed afterwards. For selective SQLs see Chapter 13., “Selective Queries or Custom Queries” on page 277, and for join SQLs see 12.2, “Multiple Table Inheritance Mapping” on page 269).

This is the straightforward Title>>#categories method:

categories

"Answers the receiver’s categories, NOT its categoryAssociations"

| categories |

Many-to-Many Associations 247

^categories := self categoryAssociations collect: [ :each | each category ]

A bit more sophisticated is the method for adding a category to a title. We need to create a new TitleToCategory link object with references to both aCategory and the title. The creation of the link object and the establishing of the necessary links are done by the createForTitle:category: in TitleToCategoryHome, which is called by the addCategory: in Title. Because Title is intended to be not only the class but also a VisualAge part, we have to implant the signaling mechanism as well.

Page 274: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

This is the TitleToCategoryHome>>#createForTitle:category: method:

createForTitle: title category: category

"Method to hide key implementation class inside home collection."

| titleToCategory |

^titleToCategory := ( self createFromKey: ( Rb50TitleToCategoryKey new title: title key;category: category key;yourself ) )

title: title;category: category;yourself.

This is the Title>>#addCategory: method:

addCategory: aCategory

"Add a category to the receiver"

| categoryAssociation |

categoryAssociation := Rb50TitleToCategoryHome singletoncreateForTitle: self category: aCategory.

self signalEvent: #categories with: self categories.^aCategory

The method for removing a category from the title’s list is a bit more complicated. First, we must look up the TitleToCategory object that holds a reference to the category to be removed from the list. There are two ways to do that: either you ask the TitleToCategoryHome to do the lookup with

248 Using VisualAge Smalltalk ObjectExtender

findByTitle:category:, or you iterate through the categoryAssociations list yourself. The problem with using the home is that after you create an object it cannot be retrieved through the home in the same transaction, because the home goes looking for it in the database. There needs to be a commit in between. So we chose the other possibility, iterating through the categoryAssociations and looking for one that references the category to be removed. Once we find the correct TitleToCategory association object, we need to disconnect the links to it from the Title object as well as from the Category object. To that end, we use the methods generated by ObjectExtender, removeCategoryAssociations in Title and removeTitleAssociations in Category. After that, we can dispose of the

Page 275: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

association object, using markRemoved. Again we have to notify observers of the change. This is the method:

removeCategory: aCategory

"Removes aCategory from the receiver"

| categoryAssociation |

"This does not work work within one transaction:categoryAssociation := Rb50TitleToCategoryHome singleton

findByTitle: self category: aCategory."

"But this does:"categoryAssociation := self categoryAssociations

detect: [ :each | each category == aCategory].self removeCategoryAssociations: categoryAssociation.aCategory removeTitleAssociations: categoryAssociation.categoryAssociation markRemoved.self signalEvent: #categorieswith: self categories.

^aCategory

The following script categorizes the Title with isbnNumber = ’123456789’. In the same transaction Category with id = 1 is added and removed. The Category with id = 2 is the final categorization.

"Categorize a title."| title category |Transaction begin.’---> get title with isbnNumber = 123456789 & category with id = 1’ vapTrace.title := Rb50TitleHome singleton findByIsbnNumber: ’123456789’.

Many-to-Many Associations 249

category := Rb50CategoryHome singleton findById: ’1’.’---> add category withy id = 1’ vapTrace.title addCategory: category.’---> remove category withy id = 1’ vapTrace.title removeCategory: category.’---> get and add category with id = 2’ vapTrace.category := Rb50CategoryHome singleton findById: ’2’.title addCategory: category.’---> commit’ vapTrace.Transaction current commit.

Page 276: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The extract from the System Transcript shows the executed SQLs.

’---> get title with isbnNumber = 123456789 & category with id = 1’

’>>>find by key’SELECT T1.author, T1.description, T1.isbnNumber, T1.publisher FROM

USERID.Rb50Title T1WHERE T1.isbnNumber = ’123456789’

’>>>find by key'SELECT T1.id, T1.name FROM USERID.Rb50Category T1WHERE T1.id = '1'

’---> add category withy id = 1’

'>>>retrieveCategoryAssociationsForRb50Title: aRb50TitleKey 'SELECT T1.category, T1.title FROM USERID.Rb50Title2Category T1WHERE T1.title = '123456789'

'>>>retrieveTitleAssociationsForRb50Category: aRb50CategoryKey 'SELECT T1.category, T1.title FROM USERID.Rb50Title2Category T1WHERE T1.category = '1'

’---> remove category withy id = 1’

’---> get and add category with id = 2’

'>>>find by key'SELECT T1.id, T1.name FROM USERID.Rb50Category T1WHERE T1.id = '2'

'>>>retrieveTitleAssociationsForRb50Category: aRb50CategoryKey 'SELECT T1.category, T1.title FROM USERID.Rb50Title2Category T1WHERE T1.category = '2'

250 Using VisualAge Smalltalk ObjectExtender

’---> commit’'>>>insert'INSERT INTO USERID.Rb50Title2Category

( title, category )VALUES ( '123456789', '2' )

Noteworthy is the retrieval of the Title2Category associations for both Category and Title in order to perform the add the new Title2Category link object for the Category with id = 1.

Page 277: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

11.3.3 Run Sample with User InterfaceIn our original scenario, we wanted an application with which the user can enter new titles, edit and delete existing titles, as well as assign categories to titles. We have now chosen to split the application into two parts:

• The first, Rb50TitleView, is for managing the titles in general, such as displaying a list, or adding and deleting titles.

• When a new title is added, or an existing title is selected for editing, the second part, Rb50TitleDetailsView, is opened. The assignment of categories can be performed there, and other title details can be entered.

Title List ViewFigure 175 shows the Rb50TitleView. Table 54 on page 253 lists the connections between the parts in Rb50TitleView.

Many-to-Many Associations 251

Figure 175. Rb50TitleView

The key features of the Rb50TitleView part are:

• The transaction for the whole application is held in Rb50TitleView. You can see the familiar interplay of the shared transaction with the top-level transaction being reused here.

Page 278: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

• The transacted title variable holds the currently selected title. The contents is filled as the result of a selection in the list box or by a new title created in the titleHome (Connection 9 or Connections 6 and 8).

• When a title is to be edited, a new Rb50TitleDetailsView part is created with the help of an Rb50TitleDetailsView factory (Connection 4) and opened (Connection 5). The transacted title is passed as a creation parameter to the factory to set the title variable promoted from the Rb50TitleDetailsView part. The Edit button functions as a funnel for all the events that can trigger the creation of an Rb50TitleDetailsView part, whether the defaultactionRequested of the container (Connection 10) or the clicked events of the New button (Connection 7), or the Edit button itself (Connection 6).

• Any changes made to the title in the Rb50TitleDetailsView are committed or rolled back on the promoted clicked events of the OK and Cancel buttons there.

252 Using VisualAge Smalltalk ObjectExtender

Page 279: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 54. Connections of Rb50TitleView

Source (S) Feature of S Target (T) Feature of T

12

deleteButtondeleteButton

clickedclicked

transacted titletopLevelTransaction

removecommit

3 (deleteButton,clicked --> topLevelTransaction,commit)

errorResult Message Prompter promptFor:

4567

editButtoneditButtonnewButtonnewButton

clickedclickedclickedclicked

TitleDetailsViewtitleDetailsViewtitleHomeeditButton

newopenWidgetcreateclick

8 (newButton,clicked --> titleHome,create)

normalResult transacted title self

9101112

titleContainertitleContainertitleContainertitleContainer

selectedItemdefaultActionRequestedselectionIsValidselectionIsValid

transacted titleeditButtoneditButtondeleteButton

selfclickenabledenabled

131415

TitleDetailsViewtitleDetailsViewtitleDetailsView

instancecancelClickedokClicked

titleDetailsViewtopLevelTransactiontopLevelTransaction

selfrollbackcommit

16 (titleDetailsView,cancelClicked --> topLevelTransaction,rollback)

errorResult Message Prompter promptFor:

17 (titleDetailsView,okClicked --> topLevelTransaction,commit)

errorResult Message Prompter promptFor:

18 titleHome allInstances titleContainer items

1920

topLevelTransactiontopLevelTransaction

committedOrRolledbackcommittedOrRolledback

sharedTransactiontitleContainer

beginChilditems

21 (topLevelTransaction,committedOrRolledback -->

normalResult topLevelTransaction self

Many-to-Many Associations 253

sharedTransaction,beginChild)

22 (topLevelTransaction,committedOrRolledback --> titleContainer,items)

value titleHome allInstances

2324

transacted titletransacted title

selftransaction

TitleDetailsViewtopLevelTransaction

titleVariableself

25 Window openedWidget sharedTransaction beginChild

26 (Window,openedWidget --> sharedTransaction,beginChild)

normalResult topLevelTransaction self

Page 280: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Title Details ViewFigure 176 shows the RB50TitleDetailsView. Table 55 on page 255 shows the connections between the parts in RB50TitleDetailsView.

Figure 176. Rb50TitleDetailsView in Composition Editor

The key features of the Rb50TitleDetailsView part shown in Figure 176 are:

• The clicked events of the OK and Cancel buttons and the title variable are promoted.

• Besides the entry fields for the title details, two list boxes are provided on this part. One is used to display the title’s categories, using the method we added before (Connection 14). The other shows all remaining categories.

254 Using VisualAge Smalltalk ObjectExtender

Its corresponding OrderedCollection (Connection 15) is initialized with allInstances of the categoryHome (Connections 18 and 19) reduced by the title’s categories (Connections 20 and 21).

• Two buttons, addCategoryButton (<<) and removeCategoryButton (>>), perform the respective actions on the title (Connections 8 and 10) and make sure the remainingCategories are adjusted (Connections 16 and 17).

The attentive reader may ask, "What happens when things go wrong?" On the one hand we deliberately left out error handling to concentrate on the essentials here. On the other hand, Chapter 15, “Concurrent Transactions”

Page 281: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

on page 325, addresses such questions as: "What happens if we open two detail views on the same title in different transactions?"

Table 55. Connections of Rb50TitleDetailsView

Source (S) Feature of S Target (T) Feature of T

12345

titletitletitletitletitle

authorisbnNumberpublisherdescriptionisNotPersistent

authorFieldisbnNumberFieldpublisherFielddescriptionFieldisbnNumberField

objectobjectobjectobjectenabled

6 okButton clicked Window closeWidget

7 cancelButton clicked Window closeWidget

8 addCategoryButton clicked title addCategory:

9 (addCategoryButton,clicked --> title,addCategory:)

aCategory remainingCategoriesList

selectedItem

10 removeCategoryButton clicked title removeCategory:

11 (removeCategoryButton,clicked --> title,removeCategory:)

aCategory titleCategoriesList selectedItem

12 titleCategoriesList selectionIsValid removeCategoryButton

enabled

13 remainingCategoriesList selectionIsValid addCategoryButton enabled

14 title categories titleCategoriesList items

15 remainingCategoriesList items remainingCategories self

16 (removeCategoryButton,clicked --> title,removeCategory:)

normalResult remainingCategories add:

17 (addCategoryButton,clicked --> title,addCategory:)

normalResult remainingCategories remove:

Many-to-Many Associations 255

18 Window openedWidget remainingCategories self

19 (Window,openedWidget --> remainingCategories,self)

value categoryHome allInstances

20 (Window,openedWidget --> remainingCategories,self)

normalResult remainingCategories removeAll:

21 ( (Window,openedWidget --> remainingCategories,self),normalResult --> remainingCategories,removeAll:)

aCollection title categories

Page 282: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

256 Using VisualAge Smalltalk ObjectExtender

Page 283: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 12. Inheritance

In the examples so far, we have looked only at more or less straightforward associations between classes—that is, relationships that would also have appeared in traditional entity-relationship modeling and are therefore quite natural to map from the object-oriented world to relational databases. One of the object-oriented concepts that cause the so-called impedance gap between the two worlds is inheritance. In this chapter, we cover the ways in which ObjectExtender helps us bridge the gap.

To do so, we concentrate on that part of the Library Management System model that consists only of the book and (especially) its status classes, as shown in Figure 177. The status of a book is always represented by one of the different subclasses of Status, so what we have here is a classic example of the state pattern. The inheritance hierarchy may seem a bit artificial in this context, but that is because we ignore the behavioral aspects that led to this design in the first place.

© Copyright IBM Corp. 1999 257

Figure 177. Library Management System: Book and Its Status

There are basically two ways to match an inheritance tree to a relational database: Either you combine all attributes of the class hierarchy in one table

Page 284: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

or you have a table for each class and establish the necessary foreign key relationships between the tables.

12.1 Single Table Inheritance Mapping

Mapping the Status class and its subclasses into one table means that we put all attributes—whether from the Status class or from any of its subclasses— into one table. In addition, a discriminator column is needed (type in table STATUS in Figure 178) that holds an indicator for the class the row belongs to, in order to tell ObjectExtender what kind of object to build when a row is read from the database.

Table BOOK

serialNumber

id book customer type startDate returnDate reservationDate endOfReservation

Table STATUS

1

2

3

1 1

22

33

-

-

Available

Borrowed

Available

999 07-07-98 08-07-98

258 Using VisualAge Smalltalk ObjectExtender

Figure 178. Example of Three Books and Their Status Mapped into a Single Table

As Figure 178 shows, there is a drawback to this approach: Depending on the structure of the data and the number of the rows, table space may be wasted. Support of the null value and the view of today’s relational database systems

unused space in table

Page 285: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

ease the problem somewhat, but mapping a class hierarchy to a single table is still appropriate primarily when:

• The subclasses differ more in their behavior than in their attributes. If the persistent objects have basically the same data, little space is wasted in the database.

• Database access speed is critical. Having everything in one table results in fewer SQL queries and therefore in better performance.

12.1.1 Define the ModelThe definition of the Book and Status model follows the same steps you have seen in previous sections. There are a few things to note, though:

• We can use serialNumber as a natural object ID for Book, but we must introduce an artificial ID for Status.

• Although an artificial ID is introduced in the Status class, it is not necessary to do so again in its subclasses. Because subclasses inherit all their parents’ attributes, the required object ID exists in all Status classes. And, there is no point in having multiple primary keys, because all attributes are mapped to one table in the database.

• Do not forget to add the one-to-one association between Book and Status with the settings shown in Figure 179.

Inheritance 259

Figure 179. Settings for the One-to-One Association between Book and Status

Page 286: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

• The important point at which this sample deviates from what you have done before is the way in which you define the subclasses of Status. This is not done by adding associations between the subclass and the superclass but by specifying the correct superclass in the Class Editor. As shown in Figure 180, you have to change the Superclass in the drop-down list box from <default> to the correct superclass—in this case Status.

Figure 180. Definition of Borrowed As Subclass of Status

12.1.2 Define the SchemaAfter you have defined the model, use the Generate schema from model

260 Using VisualAge Smalltalk ObjectExtender

feature in the Model Browser. This automatically creates a schema where the inheritance tree is mapped into one table. The resulting schema looks like the schema in Figure 181.

Page 287: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 181. Schema for the Book-Status Example after Automatic Generation

The Columns list of the Status table shows that ObjectExtender has combined all attributes from the Status class and its subclasses into one table. Observe that ObjectExtender has created an additional column to be able to distinguish the different types (Rb61Library). You can rename this column or change its type to what you think fits best; we chose type for the name and kept the default type VARCHAR(12). Note also that the column names automatically generated for the attributes of the subclasses. If you do not like the generated names, change them.

Inheritance 261

When you change the name of a foreign key relationship, a copy of the relationship with the new name is created. To resolve the problems with the foreign key relationship, follow these steps:

1. Add a new column called serialNumber of type INTEGER (see below for the justification) with no nulls allowed.

2. Change the type of the serialNumber column in the Book table to INTEGER. This is necessary because ObjectExtender currently prevents the types of the two columns in the foreign key relationship from matching if they are SMALLINT, even though that match is required.

Page 288: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

3. Change the name of the foreign key relationship from Status to Book to something like bookHasStatus. Also change the foreign key to bookSerialNumber. When you close the dialog with OK, you see that you have a new copy of the foreign key relationship.

4. Delete the old Status to Book relationship.

5. Delete the old Rb61Book_serialNumber column.

Before you finally export your schema to the database, be sure you have adjusted the table qualifiers to your needs (the default is VAP).

12.1.3 Define the MappingThe first step of mapping the Book class to the Book table is the same as we have seen in previous sections. Select Book from the list of Persistent Classes in the Map Browser, add a Cluster Map with no inheritance, and edit the property map (map serialNumber and the association to Status).

A new procedure is necessary for defining the mappings for the Status class and its subclasses. Select Status from the Persistent Classes list, add a Single Table Inheritance Map, and fill in the fields in the dialog (Figure 182).

262 Using VisualAge Smalltalk ObjectExtender

Figure 182. Table Map for Class Status

As Status is the root class of the inheritance tree, be sure you have selected the Root of the model hierarchy check box. This also allows you to choose which column is to be taken as the discriminator.

Page 289: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Note on discriminatorsA discriminator is used to distinguish between the types of database entries that might come from different classes. To that end, we already defined a discriminator column in our schema and now enter a discriminator value for every class of an inheritance tree that is mapped to the single table. This value is then automatically written when an object is stored in the database. The type of the discriminator value could be anything from the class name to some numerical class code. The default type is String (VARCHAR(12) in the database), and we did not change it in the schema. So when you add a single inheritance map, be sure that the discriminator value is a string constant in Smalltalk style—in other words, a string in single quotes.

After you have mapped the attributes and associations of Status, you also need to add a single table inheritance map for all subclasses of Status. Choose Status as the table to map to, then make sure that the Root of the model hierarchy check box is deselected, and decide on an appropriate value for the discriminator. As can be seen in Figure 183, we stick to the class name (as string).

Inheritance 263

Figure 183. Table Map for Class Available

When you edit the property maps for the subclasses of Status, do not map the attributes and associations that have already been mapped in Status again. Add only the mappings for additional attributes, such as startDate in Borrowed. Remember to map returnDate of both Borrowed and Overdue to the same column (returnDate).

Page 290: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

12.1.4 Test Single Table Inheritance Mapping SampleOnce the model, schema, and mappings are complete and saved, and the model and services code have been generated, it is time to test our sample. We test headless here, with little scripts. The scripts are in the Rb6XTstW.wsp workspace file (see Appendix C, “Downloadables, ConfigMaps, Applications” on page 355).

Set up Sample ObjectsThe first test script creates the Books and Status’ as shown in Figure 178 on page 258:

"Setup books with status."

| newBook newStatus today |today := Date newDay: 20 month: #December year: 1999.

"Begin a new TopLevelTransaction."Transaction begin.

"Create Available Book with id = 1."newBook := Rb61BookHome singleton createForSerialNumber: 1.(newStatus := Rb61AvailableHome singleton createForId: (newBook serialNumber) )

book: newBook.

"Create Available Book with id = 2."newBook := Rb61BookHome singleton createForSerialNumber: 2.(newStatus := Rb61AvailableHome singleton createForId: (newBook serialNumber) )

book: newBook.

"Create Borrowed Book with id = 3."newBook := Rb61BookHome singleton createForSerialNumber: 3.

264 Using VisualAge Smalltalk ObjectExtender

(newStatus := Rb61BorrowedHome singleton createForId: (newBook serialNumber) )

startDate: today; returnDate: (today addDays: 30);book: newBook;customer: 999.

"Commit the TopLevelTransaction."Transaction current commit.

If you look at the output on the System Transcript you see the SQL statements that ObjectExtender has built and executed. As a sample we

Page 291: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

recall the SQL statements executed for the Borrowed Book, that is the Book with the id = 3:

INSERT INTO USERID.Rb61Book( serialNumber, condition )VALUES ( 3, NULL )

INSERT INTO USERID.Rb61Status( id, type, bookSerialNumber, customer, returnDate, startDate )VALUES ( 3, ’Borrowed’, 3, 999, {d ’2000-01-19’ }, {d ’1999-12-20’ } )

The noteworthy points here are:

• The discriminator value ’Borrowed’ is added automatically because a Borrowed object was created.

• The dates operate Y2K compliant.

Verify Sample Object SetupThe next test script shows that both kind of homes, this are the (leaf) subclass and (root) superclass homes, deliver instances on an allInstances message:

• The subclass homes delivers its unique instances.

• The superclass home delivers the instances of its class, if it is the home of a concrete class, and all instances of all its subclass home classes.

The Debugger in Figure 184 shows the scripts in the list pane and the results in the inspector area. Close the Debugger by clicking on the Resume button. The executed SQL statements are:

SELECT T1.type, T1.bookSerialNumber, T1.customer, T1.idFROM USERID.Rb61Status T1WHERE T1.type IN ( ’Available’)

SELECT T1.type, T1.bookSerialNumber, T1.customer, T1.id, T1.returnDate,

Inheritance 265

T1.startDate FROM USERID.Rb61Status T1 WHERE T1.type IN ( ’Borrowed’)

SELECT T1.type, T1.bookSerialNumber, T1.customer, T1.id, T1.returnDate,T1.startDate, T1.returnDate, T1.endOfReservation, T1.reservationDate

FROM USERID.Rb61Status T1WHERE T1.type IN ( ’Overdue’, ’Available’, ’Status’, ’Borrowed’, ’Reserved’)

Note the WHERE clause setup of the SQL statements. The discriminator values are used in the IN part to select the matching rows. For the

Page 292: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

alInstances of the superclass home the IN clause includes all available discriminator values. This inspires for combined selective queries, such as allOverdueAndBorrowed instances (and books, see 13.2, “Solution” on page 278.)

Figure 184. allInstances of the Superclass and Subclass Homes

Perform End-of-Day ProcessingThe last test script is a bit more sophisticated. Imagine that the Library Management System must check at the end of every day to see which of the borrowed books have become overdue. One possibility is to go through all Borrowed objects and see whether the supposed returnDate (an attribute of Borrowed) has passed. If it has, a new Overdue object is created, and the old

266 Using VisualAge Smalltalk ObjectExtender

Borrowed object is sent the message markRemoved. This action does not actually delete the object but rather marks it to be deleted in the current transaction. It is then deleted when the transaction is committed. The procedure is this:

"End-of-Day Processing"

"For this example we assume that the end-of-day processing is run at theday after the return date of the book that was created before, so that wecan demonstrate the status change. Be aware that the dates span the Y2Kborder... and it works! VisualAge Smalltalk is Y2K compliant... and wasit since ever!"

Page 293: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

| today |today := Date newDay: 20 month: #January year: 2000.Transaction begin.

"Iterate through all Borrowed objects and look for passed return dates."Rb61BorrowedHome singleton allInstances do: [:each |

each returnDate < today ifTrue: [

"Create a new Overdue object with the attributevalues of the old Borrowed object."

(Rb61OverdueHome singleton createForId: each id)returnDate: each returnDate;customer: each customer;book: each book.

"Delete the old Borrowed object."each markRemoved ] ].

Transaction current commit.

The System Transcript output again shows the executed SQL statements, and it is instructive to take a closer look at them. The call of allInstances in the BorrowedHome singleton causes an SQL query that selects all rows with the type ’Borrowed’ from the Status table. (In an actual library, this might get very expensive, so we look at how to do it more intelligently in Chapter 13, “Selective Queries or Custom Queries” on page 277.) The next query, selected from the Book table, is caused by the navigation from Borrowed to Book in the statement each book.

There is then a delete for the old Borrowed object and an insert into the Status table for the new Overdue object. At this point, we sometimes experienced an inverse order of the SQL statements. ObjectExtender tried to insert before the delete, causing a duplicate key error. This occurred because

Inheritance 267

the Borrowed Object (with id = 1) was still around when the new Overdue object (also with id = 1) was inserted. To work around this, we could set a different ID in the new Overdue object, for example, a time stamp from the database (To make the test script work we used the Time millisecondClockValue). Another workaround and probably a general recommendation for single table inheritance mapping, is to have unique primary keys for every subclass. This is an easy solution, being a combination of id and type. (Reversing the createFor: and markRemoved order and temporarily storing the further required values from Borrowed does not help, because ObjectExtender is reordering back again the SQL

Page 294: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

statements in the resources sort on the transaction commit.) But considering the database performance by comparing the insert/delete and the update on the given single table (with the already paid space waste) questions anyway the state pattern design of the Status in Library System Design. With a single Status object, which is only changing its state, and with no Status history, the Book id foreign key as the primary key becomes the most simple solution (and shows the very tight coupling between the Book and its Status).

Tip: If your script crashes within a transaction in cases such as above, evaluate the Smalltalk expression

AbtDbmSystem startUpto reset a locked database connection.

Note: The Book table was not updated with the script above. However, the situation changes considerably if we make a small change to our end-of-day script: As the one-to-one association between Book and Status is navigable from both sides, we can build the link from the other side, from Book, not from Status as we did in the previous script. Use the following script:

| today newStatus |today := Date newDay: 20 month: #January year: 2000.

Transaction begin.Rb61BorrowedHome singleton allInstances do: [:each | each returnDate < today ifTrue: [

newStatus := ( Rb61OverdueHome singleton createForId:Time millisecondClockValue )

returnDate: each returnDate;customer: each customer;"We don’t set book in status anymore..."yourself.

"...but set the new status in book."each book status: newStatus.each markRemoved ] ].

268 Using VisualAge Smalltalk ObjectExtender

Transaction current commit.

If we do it this way, then ObjectExtender marks the book as dirty, because we changed one of its instance variables. When the transaction is committed, the change automatically causes an update to that object’s representation in the database, even though from the database point of view nothing has changed for the book table. To get the best performance, always consider the way you navigate from object to object and from which side you set up links.

Page 295: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

12.2 Multiple Table Inheritance Mapping

Mapping an inheritance hierarchy to multiple tables means putting all the common attributes of the superclass into one table but putting all of the additional attributes of subclasses into separate tables.

The tables for the subclasses then need to be linked to the superclass table with foreign key relationships. Figure 185 shows the result for the example with the three books from Figure 178 on page 258.

Table BOOK

serialNumber

1

2

3

id book customer type

Table STATUS

1 1

2

33

-

-

Available

Borrowed

Available

999

2

id

Table AVAILABLE

1

2

id startDate returnDate

3 07-07-98

Table BORROWED

08-07-98

Inheritance 269

Figure 185. Example of Three Books and Their Status Mapped to Multiple Tables

On the one hand, this results in no unused space in the tables, unlike the case with single table mapping. On the other hand, there is an overhead for combining the primary and foreign keys in the subclass tables. Furthermore, there is a penalty in terms of additional SQL statements: Reading an object from, or writing it to, the database now results in two statements. As a result, this approach may be appropriate when subclasses differ considerably

Page 296: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

in their data. Mapping very different subclasses to a single table would result in a lot of unused space.

Database access speed considerations are not paramount. It is a general law in computing that you pay for less memory consumption (in this case, for the database) with reduced performance. There is no silver bullet; you must find the trade-off that best meets your needs.

12.2.1 Define the ModelTo demonstrate multiple table mapping and to contrast it with the single table mapping, we stick to the Book and Status example from the Library Management System.

Fortunately, we can use exactly the same model as before. This shows one benefit of the ObjectExtender practice of separating modeling considerations from implementation issues.

12.2.2 Define the SchemaWe need to make some changes to the previous schema. Only the Book table remains exactly the same. For the definition of the Status table and the four subclass tables, refer to Table 56 and Table 57, respectively.

Note: In the subclass tables, ID is used as both the primary and the foreign key.

Table 56. Tables, Columns, and Attributes for Status Superclass

Table Column Name Column Type Allows Nulls

Status id INTEGER No (Primary Key)

bookSerialNumber INTEGER No (Foreign Key)

customer INTEGER Yes

270 Using VisualAge Smalltalk ObjectExtender

type VARCHAR(12) No

Page 297: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 57. Tables, Columns, and Attributes for the Subclasses of Status

Define all of the foreign key relationships, from Status to Book and from all the subclass tables to Status. The Available to Status relationship in Figure 186 on page 183 illustrates one example of these foreign key relationships.

Table Column Name Column Type Allows Nulls

Available id INTEGER No (Pr. + F. Key)

Borrowed id INTEGER No (Pr. + F. Key)

startDate DATE Yes

returnDate DATE Yes

Overdue id INTEGER No (Pr. + F. Key)

returnDate DATE Yes

Reserved id INTEGER No (Pr. + F. Key)

reservationDate DATE Yes

endOfReservation DATE Yes

Inheritance 271

Figure 186. Definition of the Foreign Key Relationship between Available and Status

Page 298: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

12.2.3 Define the MappingThe really different (and therefore more interesting) part is the definition of the mapping. For Book it is the same as before: a simple cluster map with noinheritance. For Status, however, it is quite different. Add Root/Leaf Inheritance Table Map brings up the dialog in Figure 187.

Figure 187. Definition of the Status Table Map (Root Inheritance Table Map)

Note: It is still necessary to have a discriminator column, but only in the root of the model hierarchy. (Be sure you have the respective check box selected for Status.)

The definition of the maps for the subclasses is also done with Add Root/Leaf Inheritance Table Map. But here the check box Root of the model hierarchy must be deselected. This in turn enables the Foreign key

272 Using VisualAge Smalltalk ObjectExtender

relationship drop-down list box, from which the correct relationship must be chosen. It is only here that the superclass and subclass association is established; it cannot be done on the Associations page in the Property Map notebook (see Figure 188).

Note: As with single inheritance table mapping, do not map attributes or associations of superclasses in the subclasses again.

Page 299: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 188. Definition of the Available Table Map (Leaf Inheritance Table Map)

12.2.4 Test Multiple Table Inheritance Mapping SampleOnce the model, schema, and mappings are complete and saved, and the model and services code have been generated, we are almost ready to test our sample.

Beside the insert-before-delete problem, which we faced already with single table inheritance mapping in 12.1.4, “Test Single Table Inheritance Mapping Sample” on page 264, we may exploit other pitfalls and implement some fixes as described in Appendix F.5, “SQL Execution Order in Multiple Table Inheritance Mapping” on page 398.

We test headless here, with little scripts.The scripts looks the same as in

Inheritance 273

12.1.4, “Test Single Table Inheritance Mapping Sample” on page 264—but have the class prefix RB62— and are available in Rb6XTstW.wsp workspace file (see Appendix C, “Downloadables, ConfigMaps, Applications” on page 355).

Set up Sample ObjectsThe first test script creates the Books and Status’ as shown in Figure 178 on page 258.

If you look at the output on the System Transcript you see the SQL statements that ObjectExtender has built and executed. As a sample we

Page 300: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

recall the SQL statements executed for the Borrowed Book, that is the Book with the id = 3:

INSERT INTO USERID.Rb62Book ( serialNumber, condition )VALUES ( 1, NULL )

INSERT INTO USERID.Rb62Status( id, type, bookSerialNumber, customer )VALUES ( 1, ’Borrowed’, 1, 999 )

INSERT INTO USERID.Rb62Borrowed( id, returnDate, startDate )VALUES ( 1, {d ’2000-01-19’ }, {d ’1998-12-20’ } )

The noteworthy point here is that you can see that two SQL statements are executed to store the Borrowed object:

• Insert into the Rb62Status root table (discriminator set automatically)

• Insert into the Rb62Borrowed leaf table

Verify the Sample Object SetupThe next test script verifies the sample object setup.

Execute an allInstances on all (leaf) subclass homes and on the (root) superclass home, inspect the results, and take a look at the executed SQL statements. Setting ObjectExtender’s trace level to Basic Trace in the ObjectExtender Tools menu of the displays enough for that. Setting the the trace level to Extended Trace displays also the casted and set to null columns in the union SQL statement (see SQL statement on page 275).

274 Using VisualAge Smalltalk ObjectExtender

Executing an allInstances on a (leaf) subclass home, for exmaple, Rb62OverdueHome singleton allInstances, shows that ObjectExtender executes a join SQL to read multiple table inheritance mapped leaf objects:

SELECT T1.type, T1.bookSerialNumber, T1.customer, T1.id, T2.returnDateFROM USERID.Rb62Status T1, USERID.Rb62Overdue T2WHERE (T1.id = T2.id) AND (T1.type IN ( ’Overdue’))

Page 301: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Executing an allInstances on the (root) superclass home, for example, Rb62StatusHome singleton allInstances, shows that ObjectExtender executes a union and join SQL statement:

SELECT T1.type, T1.bookSerialNumber, T1.customer, T1.id,T2.returnDate, T2.startDate, CAST(NULL AS DATE),CAST(NULL AS DATE), CAST(NULL AS DATE)

FROM USERID.Rb62Status T1, USERID.Rb62Borrowed T2WHERE (T1.id = T2.id) AND (T1.type IN ( ’Borrowed’))

UNION ALL (SELECT T2.type, T2.bookSerialNumber, T2.customer, T2.id,

CAST(NULL AS DATE), CAST(NULL AS DATE),CAST(NULL AS DATE), T1.endOfReservation, T1.reservationDate

FROM USERID.Rb62Reserved T1, USERID.Rb62Status T2WHERE (T2.id = T1.id) AND (T2.type IN ( ’Reserved’)))

UNION ALL (SELECT CAST(NULL AS VARCHAR (12)), CAST(NULL AS INTEGER),

CAST(NULL AS INTEGER), CAST(NULL AS INTEGER), CAST(NULL AS DATE), CAST(NULL AS DATE),CAST(NULL AS DATE), CAST(NULL AS DATE),CAST(NULL AS DATE)

FROM USERID.Rb62Status T1 WHERE T1.type IN ( ’Status’))UNION ALL

(SELECT T1.type, T1.bookSerialNumber, T1.customer, T1.id,CAST(NULL AS DATE), CAST(NULL AS DATE),CAST(NULL AS DATE), CAST(NULL AS DATE),CAST(NULL AS DATE)

FROM USERID.Rb62Status T1WHERE T1.type IN ( ’Available’))

UNION ALL (SELECT T1.type, T1.bookSerialNumber, T1.customer, T1.id, CAST(NULL AS DATE), CAST(NULL AS DATE), T2.returnDate, CAST(NULL AS DATE), CAST(NULL AS DATE)

Inheritance 275

FROM USERID.Rb62Status T1, USERID.Rb62Overdue T2WHERE (T1.id = T2.id) AND (T1.type IN ( ’Overdue’)))

Noteworthy points here are the third and second last SELECTs.

• The third last SELECT would deliver (root) superclass instances, if they would be concrete classes

• The second last SELECT is not a join, because the (leaf) subclass object have no unique information. They share the primary key with the primary key of its corresponding (root) superclass objects.

Page 302: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Perform End-of-Day ProcessingIn the last test script—the end-of-day processing—four SQL statements are executed for the Status change and one for the Book per status change:

• Insert into the Rb62Status root table (discriminator set automatically)

• Insert into the Rb62Overdue leaf table

• Delete from the Rb62Borrowed leaf table

• Delete from the Rb62Status root table

• Update of the Rb62Book table

The statement for the Book is executed because the Overdue Status is assigned to the Book and not vice versa (see Note on page 268). The details of the executed SQL statements are:

INSERT INTO USERID.Rb62Status( id, type, bookSerialNumber, customer )VALUES ( 39027748, ’Overdue’, 1, 999 )

INSERT INTO USERID.Rb62Overdue( id, returnDate )VALUES ( 39027748, {d ’2000-01-19’ } )

DELETE FROM USERID.Rb62BorrowedWHERE id = 1

DELETE FROM USERID.Rb62StatusWHERE id = 1

UPDATE USERID.Rb62BookSET condition = NULLWHERE serialNumber = 1

276 Using VisualAge Smalltalk ObjectExtender

Note the reverse order of the insert and delete SQL statements concerning the inheritance, the class hierarchy, and the database foreign key constraints:

• For the inserts: 1st - Status; 2nd and last - Overdue

• For the deletes: 1st - Borrowed; 2nd and last - Status

Page 303: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 13. Selective Queries or Custom Queries

As we have already seen in 12.1, “Single Table Inheritance Mapping” on page 258, there are often cases where the queries that ObjectExtender generates in the Home Collection classes are not sufficient. The queries for all instances or for a single object by key may be too broad and therefore potentially inefficient, or their scope may be too narrow. Sometimes, there is a need for queries that return a subset of all instances, determined by the values of their attributes.

Note: The terms selective queries and custom queries are synonymous.

13.1 Problem

Remember the Book and Status example where we wanted to find out all Borrowed objects that are already overdue in 12.1.4, “Test Single Table Inheritance Mapping Sample” on page 264. We used a script like:

"End-of-Day Processing"

| today |today := Date newDay: 20 month: #January year: 2000.Transaction begin.

"Iterate through all Borrowed objects and look for passed return dates."Rb70BorrowedHome singleton allInstances do: [:each |

each returnDate < today ifTrue: [

"Create a new Overdue object with the attributevalues of the old Borrowed object."(Rb70OverdueHome singleton createForId: each id)

returnDate: each returnDate;

© Copyright IBM Corp. 1999 277

customer: each customer;book: each book.

"Delete the old Borrowed object."each markRemoved ] ].

Transaction current commit.

Page 304: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

When this script is executed, the following SQL command is sent to the database, the result set is parsed, and for each object read a lot of action goes on behind the scenes:

SELECT T1.type, T1.bookSerialNumber, T1.customer, T1.id, T1.returnDate,T1.startDate

FROM USERID.Rb70Status T1 WHERE T1.type IN (’Borrowed’)

With large tables or large result sets, the approach above easily gets costly.

Note that there is already a WHERE clause because we reuse the schema where all Status subclasses were mapped to a single table. The clause is needed to select only objects of the class Borrowed.

13.2 Solution

Much better than querying all entries and then parsing them would be a query that returns the essential result set in the first place. Note that there is already a WHERE clause because we reuse the schema where all Status subclasses were mapped to a single table. The WHERE clause is required to select only objects of the class Borrowed. Therefore, we used the following SELECT statement augmented by an extended WHERE clause:

SELECT T1.type, T1.bookSerialNumber, T1.customer, T1.id, T1.returnDate,T1.startDate

FROM USERID.Rb70Status T1 WHERE (T1.type IN ( ’Borrowed’)) AND (T1.returnDate < {d ’2000-01-20’ })

To achieve this with ObjectExtender, you must:

1. Add a new SQL query string to the appropriate QueryPool class.

278 Using VisualAge Smalltalk ObjectExtender

2. Add a new method to the Home Collection class.

3. Add a new service to the Service Object class.

In Smalltalk, it is good procedure to add the new methods as extensions to the classes, packaged together in one separate application. We put all extensions into an application named Rb70LibraryXSelSQLApp.

Page 305: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

13.3 Add a New SQL Query String to the QueryPool

When you have defined your mappings for every class in your model and generated the services, a QueryPool service class (among others) is generated. To this query pool you must add a method that returns an SQL query string, just as we added the allInstancesOverdueAtDateSqlString method to Rb70LibraryRb70BorrowedQueryPool: Enter this:

allInstancesOverdueAtDateSqlString

"Return the SQL string for the query called allInstancesOverdueAtDate."

^’SELECT T1.type, T1.bookSerialNumber, T1.customer, T1.id,T1.returnDate, T1.startDate

FROM USERID.Rb70Status T1 WHERE (T1.type IN ( ’’Borrowed’’)) AND (T1.returnDate < :V1)’

Note how we used the host-variable syntax (a colon and a variable name) to put a placeholder in the string. This variable is replaced at run time with the date by which we want to select.

13.4 Add a New Method to the Home Collection Class

The home is the entry point for queries for objects of a certain class, as we have seen with the allInstances and findByPrimaryKey: queries so far. Thus, it is also the natural place to put any additional query methods. The method allInstancesOverdueAtDue: to be added in Rb70BorrowedHome does not do much, except delegating the real work to the service object and collecting the results. The script is:

allInstancesOverdueAtDate: aDate

"Answers all instances of the reciever which are/will be

Selective Queries or Custom Queries 279

overdue at a certain date."

| serviceObject |

serviceObject := self serviceObject.serviceObject session: self session;allInstancesOverdueAtDate: aDate.

^self collectServiceResultsFrom: aServiceObject

Page 306: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

We factored out the collecting of the results of the service object into a separate method (collectServiceResultsFrom:), because we can then reuse it in other query methods. Do not worry about how it works; what it does is to make the objects the service object retrieved accessible in the home:

collectServiceResultsFrom: aServiceObject

"Collects the results from aServiceObject."

| bo do results |

(aServiceObject isFinished & aServiceObject isError not) ifTrue: [results := aServiceObject oids collect: [ :anOid |

do := self lookupOidFromCache: anOid.(bo := self lookupOidFromView: anOid) notNil

ifTrue: [do home refresh: bo from: do]ifFalse: [self createRetrieved: do] ] ].

^results

13.5 Add a Service to the Service Object

The real work is done by the service object. Therefore, we need to add an allInstancesOverdueAtDate method: to the service object—in our case, Rb70LibraryRb70BorrowedServiceObject, which is called by the home’s allInstancesOverdueAtDate: method. Use this script:

allInstancesOverdueAtDate: aDate

"Answers all Borrowed objects that are/will be overdue at aDate."

’>>>executing allInstancesOverdueAtDate’ vapTrace.self manyQueryUsing: self queryPool allInstancesOverdueAtDateSqlString

280 Using VisualAge Smalltalk ObjectExtender

with: (Key with: (aDate vapAsSQLStringFor: self dataStore)).self setToCompleted.

^self result.

As the generated code shows, in the first line we send a text to the ObjectExtender trace. When the tracing option is set to Basic Trace or Detailed Trace, this text is displayed on the transcript for debugging purposes.

Page 307: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The second statement is where all the pieces of the puzzle come together. We use one of the user query helpers in RelationalServiceObject, the superclass of all service objects. We use manyQueryUsing:with:. It expects an SQL string and a key as parameters. For the SQL string, we pass to the query pool the result of the method we added before. The variable already in the SQL string is replaced by what we pass as key. In our context, the key is the date by which we want to select.

The vapAsSQLStringFor: method on the date assures that the string representation of the date is one the SQL processor understands, and not the Smalltalk standard string representation. If you want to query for a single object and not for multiple objects, you could use singleQueryUsing:with: instead of manyQueryUsing:with:. It looks this:

manyQueryUsing: queryString with: aKey

"Execute the extended service to retrieve multiple instances, cache them,and return their OIDs."

| aQuerySpec aQuery |

aQuerySpec :=AbtQuerySpec new

statement: ((SqlQueryString string: queryString) evaluate: (self genericInput: aKey));

yourself.aQuery := SqlQuery querySpec: aQuerySpec

connection: (self session connection).self executeQuery: aQuery.self allInstancesLoadCache: aQuery

The setToCompleted method sets a flag in the service object indicating that its retrieval has finished. In future versions of ObjectExtender, it may no

Selective Queries or Custom Queries 281

longer be necessary to do this explicitly.

Page 308: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

13.6 Run Sample Headless with a Script

We suggest that you try out the new "Day-End-Processing" script given here for changing the status of borrowed books. When you compare the new version using the new query with the version presented in the introduction to this chapter, you see somewhat simplified code and, most important, vastly improved performance. The new script is:

"Day-End-Processing"

| today newStatus |

today := Date newDay: 20 month: #January year: 2000.

Transaction begin.

(Rb70BorrowedHome singleton allInstancesOverdueAtDate: today)do: [:each |

newStatus := (Rb70OverdueHome singleton createForId: each id)returnDate: each returnDate;customer: each customer;book: each book;yourself.

each markRemoved ].

Transaction current commit.

282 Using VisualAge Smalltalk ObjectExtender

Page 309: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 14. Nested Transactions

In previous chapters, we have looked briefly at the way ObjectExtender handles transactions. For example, in 5.8, “Create Views with Transactions” on page 83 we show the need to have the systemwide shared transaction and an associated working transaction that we named TopLevelTransaction.

In this chapter, we develop the use of transactions further, inspired by the Library example. We use the prefix Rb80 to identify sample objects developed for this chapter.

14.1 Scenario for the Transaction

The scenario for this section is that a new book arrives at the library. We envisage a GUI design that provides separate windows for Category, Title, and Book management. To make it easier to work, the user needs to be able to have the Category, Title, and Book management windows open simultaneously so that he or she can:

• Locate the book title, and if not yet available, enter the book title details (title description, author, publisher).

• Locate the primary and secondary categories for the book title, and—if necessary—add new categories to the category tree. To add new categories, the user may want to open several category windows at the same time in order to browse and maintain the entire category tree.

• Add the located primary and secondary categories to the book title.

• Enter information about the individual books (there may be more than one copy of each title).

In any one window, the user needs to be able to make and discard changes without affecting what is displayed in other windows. When the user

© Copyright IBM Corp. 1999 283

commits a change in one window, it is then propagated to the other windows. And only when the user is happy with all the changes and commits them is the total set of changes committed to the database. We suppose that the maintenance of a book title and its copies and the maintenance of the category tree have their own nested transaction hierarchy.

Before we start to implement the scenario, we take a closer look at the nested transaction problem.

Page 310: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

14.2 The Nested Transaction Problem

In previous samples, we used the construct illustrated in Figure 189, with connections summarized in Table 58, to create our transaction.

Figure 189. Typical Transaction Construct

Table 58. Connections of a Typical Transaction Construct

Source (S) Feature of S Target (T) Feature of T

1 pbCancel clicked transaction rollback

2 pbOKSave clicked transaction commit

284 Using VisualAge Smalltalk ObjectExtender

3 transaction committedOrRolledback parentTransaction beginChild

4 (transaction,committedOrRolledback --> parentTransaction,beginChild)

normalResult transaction self

5 Window aboutToOpenWidget parentTransaction beginChild

6 (Window,aboutToOpenWidget --> parentTransaction,beginChild)

normalResult transaction beginChild

Page 311: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The key feature of the construct Figure 189 is that the Cancel and OK/Save buttons rollback and commit the transaction. The transaction’s committedOrRolledback event in turn invokes the parent transaction’s beginChild action to instantiate a new transaction. (A transaction effectively dies when it is committed.)

14.3 How Not to Create the Transaction Tree

When you want to use nested transactions, you cannot use this construct. Consider the following example, which shows a nested transaction sequence, implemented using the construction in Figure 189 on page 284. We implement this sample as a thought exercise, without real code.

Figure 190. Nested Transaction Views

In Figure 190, we have two views, V1 and V2, where V1 is the parent of V2.

Parent Transaction Parent Transaction

Child Transaction Child Transaction

V1 - Parent View V2 - Child View

T1

T2

T2

T3

Nested Transactions 285

We also have three transactions, T1, T2 and T3. We consider T2 as the working transaction in V1 because it is the transaction that will handle the commit in VI. However, T2 is the parent transaction in V2, so the working transaction in V2 is T3.

As these transactions are living objects, we need to keep track, during our discussion, of the instances of each of these transactions. To do so, when a transaction is first instantiated, we refer to it as, for example, T1.1. When the transaction is committed and re-instantiated, we refer to it as T1.2, and so on.

Page 312: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Our starting state can therefore be represented by the tuple {T1.1, T2.1, T3.1}.

If we click on the Save button in V2, the Figure 189 construct works. Because there has been no change to T2, it is still a valid parent for T3. After the commit in V2, the construct in Figure 189 creates a new instance of T3, so the current state is now represented by the tuple {T1.1, T2.1, T3.2}.

We now click on the Save button in V1. This fires the commit action in T2, which in turn forces a commit on all child transactions of T2. The overall sequence of events is:

1. T2.1 commit action is invoked.

2. T2.1 forces a commit on all its children.

3. T3.2 commit action is invoked by CommitChildren from T2.1.

4. T3.2 commit fires the committedOrRolledBack event as part of its completion activities.

5. The current parent, T2.1, carries out the beginChild action and creates T3.3. Remember that T2.1 is the parent of T3.3.

6. Once all T2.1’s children have committed, T2.1 carries out its own commit actions. As part of its completion activities, it fires the committedOrRolledBack event. T1.1 receives this and creates a new child, T2.2, so that T2.1 is now effectively dead.

At the end of the commit sequence, the state can be represented by the tuple {T1.1, T2.2, T3.3}. On the surface, this looks okay. We have committed the changes and have built new transactions. However, we need to look much more carefully at T3.3. When this was created in Step 5, it was created with a parent of T2.1. However, T2.1 is now dead, having been replaced by T2.2 in Step 6.

T3.3 therefore has an invalid parent, which causes all sorts of unpleasant

286 Using VisualAge Smalltalk ObjectExtender

problems. You can, if you want, try to create a nested transaction example based on this construct. If you do so, you should ensure that you have saved your code and image before starting. You should also be prepared to kill the VisualAge process forcibly.

14.4 A Better Way to Create the Transaction Tree

The problem with the first nested transaction attempt was with Connections 1, 2, 3, and 4 in Table 58 on page 284. These connections caused a new child

Page 313: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

transaction to be built too early. Instead, it is necessary to delay any attempt to create child transactions until the commit has completed.

Furthermore, the new child transactions must be created top-down so that there is always a parent transaction for the new child. The essentials of one construct for doing this is shown in Figure 191 with the main connections listed in Table 59. We have introduced the View as child view and the transacted business object as aBOWithDataObject to illustrate the interaction with the child view and the transacted business object.

Figure 195 on page 292 shows the complete construct with all connections—the connections listed in Table 60 on page 293 and Table 61 on page 294. Table 63 on page 296 lists the View scripts to create the transaction ID (derived from the set time), the set times, and the title for the childView.

Nested Transactions 287

Figure 191. Possible Construct for Recreating the Transaction Tree

The main features of the construct in Figure 191 are:

• The nilChecker and sharedTransaction parts are used to initialize the parentTransaction with the sharedTransaction in the case where the View is the top-level view of a view and transaction tree.

Page 314: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

• The parentTransaction of childView is actually not required. It is set through the transaction valueHolder o------------o View parentTransaction connection (Connection 23) at childView creation time.

• Watch the source feature of Connection 21: Not the self—which is the value of the transaction variable as it is usually passed to the View factory parentTransaction—but the valueHolder. If the value only is passed, all childViews but the most recent loose connection to the transaction variable and do not anymore receive the new transaction through the parentTransaction self -------> transaction self event-to-action connection (Connection 9) on a commit of the transaction in order to build their new transaction.

• If the transaction is a topLevelTransaction and writes to the persistent data store, the Save/OK button has Save as label. If the transaction is a nested transaction, the label is OK. In this sample, the nilChecker supplies the required triggers to set the different lables.

• The openOwnedWidget of the childView ensures that a closeWidget on a view closes also its childViews (Connection 15).

• Watch Connection 1: The promoted transactionCommitted in any childView forces the unlisted action feature updateValueFeatures of the transactedVariable to be executed to ensure updates in the parent View. For convenience, the transactionCommittedOrRolledback feature is also promoted.

• Since LinkCollections are not evented, Connection 1 is not enough to refresh the View. Collection refresh, such as Connections 2 and 3 are required for every collection of the aBOWithDataObject business object which displayed in the View. If many collections of the business object are displayed in a view, the view part becomes more cluttered with connections than desired. Therefore we implemented the Rb80Signaller part to handle this (see signaller in Rb80CategoryDetailView part in left bottom corner of Figure 201 on page 317 and Connections 9 and 11 in

288 Using VisualAge Smalltalk ObjectExtender

Table 74 on page 320).

• The rollback of the transaction triggered by the closedWidget event of the View ensures that no active transaction is left over when the window is closed (Connection 29).

Page 315: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 59. Main Connections of Rb80TransactionExample2View

Source (S) Feature of S Target (T) Feature of T

1 childView transactionCommitted

aBOWithDataObject updateValueFeatures

2 childView transactionCommitted

list items

3 (childView,transactionCommitted --> list,items)

value aBOWithDataObject xyz (1-to-many)

9 parentTransaction self transaction self

10 (parentTransaction,self --> transaction,self)

value parentTransaction beginChild

14 pbNew clicked View new

15 pbNew clicked childView openOwnedWidget

16 pbOKSave clicked transaction commit

17 pbOKSave clicked parentTransaction beginChild

18 (pbOKSave,clicked --> parentTransaction,beginChild)

normalResult transaction self

23 transaction valueHolder View parentTransaction

25 transaction self aBOWithDataObject transaction

27 View instance childView self

29 view closedWidget transaction rollback

Nested Transactions 289

Page 316: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The arrows in Figure 192 show the creation sequence of the transaction tree in the view tree.

View new openWidget

openOwnedWidget

290 Using VisualAge Smalltalk ObjectExtender

Figure 192. View Tree with Nested Transactions at Runtime

Page 317: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The view hierarchy is visible through the view titles. The view with the View title was created first and hosts a topLevelTransaction as transaction. Therefore the Save/OK button has Save as label. From View the views with the titles 01:17<View and 01:22<View are created second and third. Their parent transaction is the View’s transaction. From 01:22<View the views with the titles 01:31<01:22 and 01:36<01:22 are created last.

Clicking on the Save button of the top-level view (View window) commits the transaction. Because of the Transaction’s implementation the commit is propagated to their children and so to the child views. No new transactions are generated during the commit propagation. After the control returns to the Save button, the second clicked event-to-action connection is fired and creates and sets the new transaction. Because the transaction valueHolder was passed to the (feature promoted) parentTransaction of the childViews, the self event of the parentTransaction in each childView is fired and creates and sets the new transaction—now in the childViews, and therefore in their childViews..., and so on and so forth. The sequence is easy to recognize by the set times of the transactions. Each getting the Set msClkV (millisecondClockValue) time has a built-in 100 millisecond delay which explains the sequence (1)20009 - (2)20149 - (3)20250 - (4)20350 - (4)20450 - (5)20550 - (6)20650 - (7)20750 - (8)20850.

Figure 193 and Figure 194 show an inspection dialog for transactions and nested transactions. In the Status Tool, select Inspect-> Inspect Transaction from the menu bar. In the Which transation dialog, select the shared transaction from the list to inspect a full tree.

Nested Transactions 291

Figure 193. Select Transaction to Inspect

Page 318: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 194. Inspection of the Top-Level Transaction and Transaction Tree

292 Using VisualAge Smalltalk ObjectExtender

Figure 195. Rb80TransactionExample2View

Page 319: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 60. Connections of Rb80TransactionExample2View (Part 1 of 2)

Source (S) Feature of S Target (T) Feature of T

1 childView transactionCommitted

aBOWithDataObject updateValueFeatures

2 childView transactionCommitted

list items

3 (childView,transactionCommitted --> list,items)

value aBOWithDataObject xyz (1-to-many)

4 nilChecker isNil parentTransaction self

5 nilChecker isNil pbOKSave object

6 nilChecker notNil pbOKSave object

7 (nilChecker,isNil --> parentTransaction,self)

value sharedTransaction self

8 parentTransaction self Rb80TransactionExample2View parentTrx:

9 parentTransaction self transaction self

10 (parentTransaction,self --> transaction,self)

value parentTransaction beginChild

11 pbCancel clicked transaction rollback

12 pbCancel clicked parentTransaction beginChild

13 (pbCancel,clicked --> parentTransaction,beginChild)

normalResult transaction self

14 pbNew clicked View new

15 pbNew clicked childView openOwned

Nested Transactions 293

Widget

16 pbOKSave clicked transaction commit

17 pbOKSave clicked parentTransaction beginChild

18 (pbOKSave,clicked --> parentTransaction,beginChild)

normalResult transaction self

Page 320: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 61. Connection of Rb80TransactionExample2View (Part 2 of 2)

Source (S) Feature of S Target (T) Feature of T

19 Rb80TransactionExample2View

TID trxID object

20 Rb80TransactionExample2View

parentTID parentTrxID object

21 Rb80TransactionExample2View

TSet trxSet object

22 Rb80TransactionExample2View

parentTSet parentTrxSet object

23 transaction valueHolder View parentTransaction

24 transaction self Rb80TransactionExample2View

trx:

25 transaction self aBOWithDataObject transaction

26 view aboutToOpenWidget

nilChecker check

27 View instance childView self

28 View instance childView title

29 view closedWidget transaction rollback

30 (view,aboutToOpenWidget --> nilChecker,check)

anObject parentTransaction self

31 (View,instance --> childView,title)

value Rb80TransactionExample2View

childTitle

294 Using VisualAge Smalltalk ObjectExtender

Page 321: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 62. Transaction ID Scripts of Rb80TransactionExample2View

Rb80TransactionExampleView2>>#methods (transaction ID scripts)

parentTrx: aTrx

"Determine and signal parentTransaction set time and ID."

| time trxName |aTrx == nil ifTrue: [

self signalEvent: #parentTSet with: ’???’.^self signalEvent: #parentTID with: ’???’ ].

time := ( ( ’00000’ , (Time millisecondClockValue \\ 100000) printString) reverse copyFrom: 1 to: 5) reverse.

(Delay forMilliseconds: 100) wait.aTrx name = ’Shared’

ifTrue: [trxName := ’Shared’]ifFalse: [trxName := aTrx abtAtAttribute: #transactionName].

(trxName = ’Unknown’ or: [trxName = ’transaction’]) ifTrue: [aTrx abtAtAttribute: #transactionName put: (trxName := time) ].

self signalEvent: #parentTSet with: time.self signalEvent: #parentTID with: trxName.

trx: aTrx

"Determine and signal transaction set time and ID."

| time trxName |aTrx == nil ifTrue: [

self signalEvent: #TSet with: ’???’.^self signalEvent: #TID with: ’???’ ].

time := ( ( ’00000’ , (Time millisecondClockValue \\ 100000) printString) reverse copyFrom: 1 to: 5) reverse.

(Delay forMilliseconds: 100) wait.aTrx name = ’Shared’

ifTrue: [trxName := ’Shared’]ifFalse: [trxName := aTrx abtAtAttribute: #transactionName].

Nested Transactions 295

Note: The transaction ID script uses the #parentTSet, #parentTID, #TSet, and #TID events, each with a String as argument. The events must be defined in the public interface of the Rb80TransactionSample2View in order supply the connections 16 through 19 to update the transaction information fields.

(trxName = ’Unknown’ or: [trxName = ’transaction’]) ifTrue: [aTrx abtAtAttribute: #transactionName put: (trxName := time) ].

self signalEvent: #TSet with: time.self signalEvent: #TID with: trxName.

Page 322: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 63. Title Scripts of Rb80TransactionExample2View

14.5 The Easy Way to Create a Transaction Tree

Use the businessTransaction to create transaction trees and make life easy.

The businessTransaction has built-in support to create a top-level transaction, when necessary. Also, it forces the top-down propagation of the new transaction, if not told otherwise (see explanation of rollbackTransactionWhenParentChanges setting in the last paragraph of 5.8.2, “Use the BusinessTransaction Part” on page 90—just in front of 5.9,

Rb80TransactionExampleView2>>#methods (title scripts)

shortTimeString

"Return mm:ss string form Time now."

| time |

time := Time now.^(time minutes printStringRadix: 10 padTo: 2)

, ’:’ , (time seconds printStringRadix: 10 padTo: 2)

childTitle

"Return childTitle of the structure: childCreationTime<parentCreationTime"

| parentTitle end |(end := (parentTitle := self title) indexOf: $<) = 0

ifTrue: [end := parentTitle size + 1].^self shortTimeString

, ’<’ , (parentTitle copyFrom: 1 to: end - 1)

296 Using VisualAge Smalltalk ObjectExtender

“Run Sample with User Interface” on page 96).

Figure 196 shows a typical construct using the businessTransaction. Because the businessTransation is lazy in initializing the transaction and only partially signals events, it is hard to build an illustrative sample such as the Rb80TransactionExample2View.

Page 323: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 196. Typical businessTransaction Construct

Note: The self attribute feature of the parentBusinessTransaction is promoted as parentBusinessTransaction. To trigger updates in the parent view, you may promote the committed (and rolled back) features also.

Table 64 lists the connections of Rb80TransactionExample3View.

Table 64. Connections of Rb80TransactionExample3View

Source (S) Feature of S Target (T) Feature of T

1 businessTransaction self View parentBusinessTransaction

Nested Transactions 297

2 parentBusinessTransaction transaction businessTransaction parentTransaction

3 pbNew clicked View new

4 pbNew clicked childView openOwnedWidget

5 pbOKSave clicked businessTransaction commit

6 View instance childView self

Page 324: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

14.6 Define Model (Metadata)

We implement just the Title, Category, and Book classes of the overall library sample class diagram. The class diagram in Figure 197 shows the scope of the implemented classes and associations.

Title

Book

Title2Category

CategoryprimaryCategory

categoryAssociations

title category

primaryTitles

title

books

subcategory

parentcategory

parentcategoryLink

1

*

*

* *

* 1

1

*

{parentcategory}

{subcategories}

{secondaryCategories} {secondaryTitles}

11

categoryHasSubcategory

titleHasbooks

titleHasPrimaryCategory

tcToCategorytcToTitle

categoryHasParentcategory

>>isbnNumber__description__author__publisher

>>categoryId__categoryTitle

>>(r)title>>(r)category

Title-Book-Category Class Diagram

* *{titleHasSecondaryCategories}

titleAssociations

Links

1

1

{categoryHasSubcategies}

Link

Links

298 Using VisualAge Smalltalk ObjectExtender

Figure 197. Class Diagram of Title-Book-Category Management System Model

CategoryLink

subcategory1

Class NameRole NameAssociaton Name{conceptual Names}

Key:

>>serialNo__condition

>>object ID (attribute)>>(r)object ID (association,

__attribute (value)

>>(r)parent

relation)

category>>(r)sub

category

Page 325: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The class Rb80CategoryLink is not necessarily required, as the self referencing Department in Chapter 7, “Employee and Department Top-Down” on page 127 proves; but with a link class, the sample shows how to implement a solution for the bill of material problem. The link objects in the bill of material solution carry additional information about the composition; for example, the number of each subpart. In the category sample as exercised now, the link objects could carry the number for the decimal classification system or sort information.

Strictly speaking, the >>(r)subcategory association attribute is sufficient to identify the CategoryLink objects, but for the foreign key mapping ObjectExtender, it also requires the (r)parentcategory association attribute to be part of the primary key (see Note on page 301).

The details for the model definition are set out in Table 65 on page 299 and Table 66 on page 300.

Table 65. Attribute Details for the Title, Category, and Book Classes

Class Attribute Attribute Details

Rb80Category categoryId String, required, object Id

categoryTitle String, required

Rb80CategoryLink - -

Rb80Title author String, required

description String

isbnNumber String, required, object Id

publisher String, required

Rb80Book condition String

serialNo Integer, required, object Id

Nested Transactions 299

Note: In the implemented sample, the Rb80CategoryLink class has only association attributes, and the issue of many-to-many relationships is addressed separately in Chapter 11, “Many-to-Many Associations” on page 241.

Page 326: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 66. Association Details for the Title, Category, and Book Classes

When we saved the model, we used the application names shown in Table 67 and accepted the default storage class names when offered.

Table 67. Application Names for Rb80 Model, Schema, and Mapping

Before proceeding to the next step, you should also generate the model code

Association Class 2 (left side in Editor)

Role of Class 1 Class 1 (right side in Editor)

Role of Class 2

categoryHasParentcategoryLink

Rb80Category parentcategoryLinknavigable

Rb80CategoryLink

subcategorynavigablerequired

categoryHasSubcategoryLinks

Rb80Category subcategoryLinksnavigablemany

Rb80CategoryLink

parentcategorynavigablerequired

titleHasPrimaryCategory Rb80Title primaryCategorynavigablerequired

Rb80Category primaryTitlenavigablemany

tcToTitle Rb80TitleToCategory

titlenavigablerequired

Rb80Title parentCategorynavigablerequired

titleHasBooks Rb80Title booksnavigablemany

Rb80Book titlenavigablerequired

Item Application Name

Model Rb80LibraryModelApp

Schema Rb80LibrarySchemaApp

Mappings Rb80LibraryMapApp

300 Using VisualAge Smalltalk ObjectExtender

classes, using the Generate... command in the Model Browser. Although it is not strictly necessary to do this before proceeding to the next stand, it is good practice. Just prior to generating the service classes in 14.9, “Generate Service Classes” on page 304, you must have generated the model code classes.

14.7 Generate Schema (Metadata)

The Entity-Relationship (ER) in Figure 198 gives an overview of the schema.

Page 327: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Title

Book

Title2Category

Category

CategoryLink

*

* *

* 1

1

*

11

categoryHasSubcategory

titleHasBooks

titleHasPrimaryCategory

tcToCategorytcToTitle

Entity & Table NameKey:

categoryHasParentcategory

>>isbnNumber

>>serialNo

__description__author__publisher

__condition

>>categoryId__categoryTitle

>>primary key

>>(r)isbnNumber>>(r)categoryId

>>(r)parent

Title-Book-Category ER Diagram / Schema

Links

1

1

Link

(r)categoryId

>>(r)sub

(r)isbnNumber

categoryId

categoryId

Nested Transactions 301

Figure 198. ER Diagram and Schema of the Title-Book-Category Management System

Note: The (r)parentcategoryId foreign key in the CategoryLink entity and table must be part of the primary, because ObjectExtender fails in the map consistency check on the one-to-many categoryHasSubcategoryLinks association. ObjectExtender makes the check without considering that the categoryHasParentCategoryLink association is a one-to-one association

1Relation Name

>>(r)primary & foreign key

__attribute(r)foreign key

Page 328: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

between the same tables as the one-to-many categoryHasSubcategoryLinks association, and therefore, the (r)subcategoryId foreign key would be unique enough to be the sole primary key component. The (r)subcategoryId foreign key is unique enough, because only one CategoryLink object can exist per Category. Defining a foreign key independent primary key for the CategoryLink table, for example, categoryId with the additional and corresponding attribute as object ID in the CategoryLink class, solves the problem, but creates difficulties in setting the primary key value or keeping it in synch with the subcategoryId foreign key.

You may use the Generate schema from model command in the Model Browser to generate the schema and data store mappings. If you define the schema manually in the Schema Browser, use the information in Figure 198, Table 68, and Table 69.

The table and column details are shown in Table 68.

Table 68. Schema Definitions for Rb80 Sample Tables

Table Column Definition Comment

Rb80Category categoryTitle VARCHAR(50) NOT NULL

categoryId VARCHAR(12) NOT NULL Primary Key

Rb80CategoryLink subcategoryId VARCHAR(12) NOT NULL Primary Key

parentcategoryId VARCHAR(12) NOT NULL Primary Key

Rb80Title author VARCHAR (64) NOT NULL

description VARCHAR (64)

isbnNumber VARCHAR(13) NOT NULL Primary Key

primaryCategoryId VARCHAR(12) NOT NULL

publisher VARCHAR (64)

302 Using VisualAge Smalltalk ObjectExtender

The foreign key details are shown in Table 69. If you define the schema manually, you have the opportunity to use logical and physical names of your choice for the columns, foreign keys, and qualifier. If you generated the schema, you may change the column and foreign key names for better

Rb80Book condition VARCHAR (128)

isbnNumber VARCHAR(13) NOT NULL

serialNo INTEGER NOT NULL Primary Key

Page 329: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

readability. You also need to change the generated qualifier for each table to one that is relevant to your database.

Table 69. Foreign Key Definitions for the Rb80 Sample

When you have completed and saved the schema details (see Table 67 on page 300 for details of the application names we used), it is a good idea to generate the physical database, using the Export Entire Schema to database command in the Schema Browser. Remember to check the System Transcript for errors.

14.8 Generate Mappings (Metadata)

When you have successfully completed and saved the schema details, it is time to turn to the data store mappings. If you use the Map Browser to look at the generated table maps, you see broken elements if you made changes to

Foreign Key Name(physical name, if different from logical)

Primary Key Table and Column

Foreign Key Table and Column

categoryHasParentcategoryLink(parentcategoryLink)

Rb80Category(categoryId)

Rb80CategoryLink(subcategoryId)

categoryHasSubcategoryLink(subcategoryLink)

Rb80Categor(categoryId)

Rb80CategorLink(parencategoryId)

tcToCategory Rb80Category(categoryId)

Rb80Title2Category(categoryId)

tcToTitle Rb80Title(isbnNumber)

Rb80Title2Category(isbnNumber)

titleHasBook Rb80Title(isbnNumber)

Rb80Book(isbnNumber)

titleHasPrimaryCategory(primaryCategory)

Rb80Category(categoryId)

Rb80Title(primaryCategoryId)

Nested Transactions 303

the schema other than the qualifier and physical names. When we developed the sample, we elected to delete the automatically generated data store map and generate it from scratch, primarily because we did not like the supplied map name, Rb80LibraryRb80library. You may, however, choose to amend the generated map by deleting the bad relationships and supplying replacements. We named our new map Rb80Library.

When we saved it, we used the application name from Table 67 on page 300.

The relevant mapping details are set out in Table 70.

Page 330: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 70. Mapping Details for the Rb80 Sample

Class and Table Attribute and Association Role Column and Foreign Key

Rb80Category categoryId categoryId

categoryTitle categoryTitle

parentcategoryLink categoryHasParentcategoryLink

primaryTitles titleHasPrimaryCategory

subcategoryLinks categoryHasSubcategoryLinks

titleAssociatons tcToCategory

Rb80CategoryLink parentcategory categoryHasSubcategoryLinks

subcategory categoryHasParentcategoryLink

Rb80Title author author

description description

isbnNumber isbnNumber

publisher publisher

books titleHasBook

primaryCategory titleHasPrimaryCategory

secondaryCategoryAssociations tcToTitle

Rb80Book condition condition

serialNo serialNo

title titleHasBooks

Rb80TitleToCategory(Rb80Title2Category)

category tcToCategory

title tcToTitle

304 Using VisualAge Smalltalk ObjectExtender

14.9 Generate Service Classes

After you have updated and saved the data store mappings, it is time to generate the real service classes. Before doing this, however, check that you have used the Model Browser to generate the real model classes. Use the Generate Services command on the Map Browser to generate the real service classes. Again, remember to check the System Transcript (trace level set to Basic Trace) for errors during the generation process. ObjectExtender makes consistency checks and reports errors to you.

Page 331: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

14.10 Hiding the Auxiliary CategoryLink Class

In this section we show how to add a number of features to the sample to hide the CategoryLink class from the Category class user. The relevant changes of the classes are summarized below.

14.10.1 Deletion of a Subcategory and Its Associated Link ObjectThere are two strategies for handling the deletion of items in a tree structure such as the categories tree:

• Node deletion: Delete the category and all its subcategories all the way down through the bottom subcategories

• Leaf deletion only: Delete a category only, when it has no subcategories

For this sample, we choose the second strategy, namely, that it should not be possible to delete an Rb80Category that has subcategories.

We therefore add an event to the Rb80Category with the name validationError. This event takes an AbtError as a parameter. We add code for the abtRemove method:

abtRemove

"Perform the remove action on self and the connected CategoryLink.NOTE: this method overrides that in the framework."

"First, delete the dependent subcategories if we want cascade delete""self subcategories do: [:each | each abtRemove]."

"But if no cascade delete, do this instead"| parentcategoryLink |self subcategories isEmpty ifFalse:

Nested Transactions 305

[| err | self signalEvent: #validationError with: ( err := AbtError newerrorText: ’Cannot delete a category that has subcategories’;yourself ).

^err ].

(parentcategoryLink := self parentcategoryLink) ~~ nil ifTrue: [parentcategoryLink abtRemove ].

super abtRemove.

Page 332: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

14.10.2 Finding the Subcategories DirectlyWe add a new public interface attribute and associated get selector, both named subcategories. We specify that the attribute data type is an OrderedCollection.

We add a method subcategories with the following script:

subcategories

"Return the value of mySubcategories as an OrderedCollection.Do not include the case where a category is its own parent (root category)"

^( ( (self subcategoryLinks collect: [:each | each subcategory])asSortedCollection: [:a :b | a referenceString < b referenceString] ) asOrderedCollection )remove: self ifAbsent: [];yourself.

14.10.3 Setting and Getting the Parent Category DirectlyFirst, we add a new attribute, parentcategory, to the Rb80Category class, using the Public Interface Editor. We then add the new setter and getter methods using the Script Editor. These are the setter and getter methods:

parentcategory: aCategory

"Save the value of parent. Create a new Rb80CategoryLink if one does not exist."

| categoryLink |

aCategory == nil ifTrue: [^self].

306 Using VisualAge Smalltalk ObjectExtender

(categoryLink := self parentcategoryLink) == nil ifTrue: [aCategory addSubcategory: self ]

ifFalse: [ categoryLink parentcategory removeSubcategories: categoryLink.aCategory addSubcategoryLinks: categoryLink ].

self signalEvent: #parent with: aCategory.

self signalEvent: #parentcategoryReferenceString with:self parentcategoryReferenceString

Page 333: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

parentcategory

"Return the the parent category, navigating through the associated categoryLink."

| categoryLink |(categoryLink := self parentcategoryLink) == nil ifTrue: [^nil].^categoryLink parentcategory

14.10.4 Adding and Removing a Subcategory DirectlyFirst, we add new actions, addSubcategory and removeSubcategory parentcategory, to the Rb80Category class, using the Public Interface Editor. We then add the addSubcategory: and removeSubcategory: methods using the Script Editor. The adding and removing of a category also adds and removes the associated CategoryLink object. The signalEvent:with: methods, such as referenceString, parentcategoryReferenceString, parentcategory, and subcategories, ensure the notification of dependents.

These are the methods:

addSubcategory: aCategory

"Add aCategory as a subcategory."

| categoryLink |

self addSubcategoryLinks: ((categoryLink := Rb80CategoryLinkHome singleton create)

parentcategory: self;subcategory: aCategory;yourself ).

Nested Transactions 307

aCategory signalEvent: #parentcategory with: self.

aCategory signalEvent: #parentcategoryReferenceString with: self referenceString.

self signalEvent: #subcategories with: self subcategories

Page 334: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

removeSubcategory: aCategory

"Remove aCategory from subcategories."

| categoryLink |

self removeSubcategoyLinks:(categoryLink := aCategory parentcategoryLink).

aCategory abtRemove.categoryLink abtRemove.

self signalEvent: #subcategories with: self subcategories

14.11 Add Some Convenience to the Category

For the programmer’s convenience, add the following to the Category and CategoryHome class:

• Reference string methods for reasonable display of references

• An allInstances method for returning all instances sorted

14.11.1 Reference String MethodsTo display references reasonably, add the following methods to the Category class:

referenceString

"Delivers a meaningful string representing the category."

| tempString |

308 Using VisualAge Smalltalk ObjectExtender

^(WriteStream on: String new)nextPutAll: ( (tempString := self categoryId) ~~ nil

ifTrue: [tempString]ifFalse: [’nil’] );

nextPutAll: ’, ’;nextPutAll: ( (tempString := self categoryTitle) ~~ nil

ifTrue: [tempString]ifFalse: [’???’] );

contents

Page 335: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

parentcategoryReferenceString

"Delivers a meaningful string representing the parentcategory."

| parentcategory |

^(parentcategory := self parentcategory) ~~ nilifTrue: [parentcategory referenceString]ifFalse: [’???’]

Also, add the attribute feature to the public interface (getter and event only).

14.11.2 All Instances SortedThere are two ways to return the all instances sorted:

• Add, for example, an ORDERD BY categoryId ASC clause to the allInstances SQL string method:

#Rb80LibraryRb80CategoryQueryPool>>#allInstancesSqlString

"Return the SQL string for the query called allInstances"

^’SELECT T1.categoryId, T1.categoryTitleFROM USERID.Rb80Category T1ORDER BY T1.categoryId ASC’

• Override the inherited allInstances method in the CategoryHome class by adding the following method:

allInstances

Nested Transactions 309

"Return all instances sorted by categoryId, ascending."

^( super allInstances asOrderedCollection asSortedCollection:[ :a :b | a categoryId < b categoryId ] ) asOrderedCollection

14.12 Run Samples Headless with Scripts

Once you have created all the real class code and amended it as detailed in 14.10, “Hiding the Auxiliary CategoryLink Class” on page 305, you can carry out headless testing of the code.

Page 336: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The next stage is to build a visually implemented application using nested transactions. We concentrate on management of the category object, as this illustrates the nested transaction problem best.

14.13 The Category Management System Application

This application consists of two views:

• The first view—Rb80CategoryList1View (Figure 199)—presents a list of categories and subcategories and provides access to the second view. It also provides functions to generate new root categories and refresh the list from the database.

• The second view—Rb80CategoryDetailView (Figure 201 on page 317)— allows the title of a category to be amended and subcategories to be added. It also provides the function to delete a category.

The view implementations follow the concepts used in 6.5, “Adding the User Interface” on page 115 and 14.4, “A Better Way to Create the Transaction Tree” on page 286.

14.13.1 Category List ViewActually, there are three list views. Each of them behaves differently towards the transactions of the detail views when refreshing the list. The behavior depends on how the home is attached and in which transaction context the allInstances is executed.

1st List ViewFigure 199 shows the Rb80CategoryList1View. The composition is very straightforward. The connection details for the Rb80CategoryList1View part are listed in Table 71 on page 314.

The key features of the Rb80CategoryList1View in Figure 199 are:

310 Using VisualAge Smalltalk ObjectExtender

• All actions run in the read-only sharedTransaction.

• Opening the window, clicking on the Refresh button, and any toplevelTransaction committing categoryDetailView fill the list with the actual categories from the database, using categoryHome>>#allInstances method.

• Clicking on the New Root button performs the following actions to enter the root category details:

1. Creates a new categoryDetailView instance, using the CategoryDetailView factory and #new message.

Page 337: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

2. Creates a new Category instance, using the categoryHome>>#create message, and store it in the promoted tempCategory variable of the newly created categoryDetailView.

3. Opens the newly created categoryDetailView instance using the #openWidget message.

Figure 199. Rb80CategoryList1View

• Double-clicking on a Category in the list performs the following actions to amend a Category, create and add subcategories, remove subcategories,

Nested Transactions 311

and delete the Category:

1. Selects the double-clicked Category.

2. Creates a new categoryDetailView instance, using the CategoryDetailView factory and #new message.

3. Stores the selected Category in the promoted tempCategory variable of the newly created categoryDetailView.

4. Opens the newly created categoryDetailView instance using the #openWidget message.

Page 338: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

• The read-only sharedTransaction automatically becomes the promoted parentTransaction of any newly created categoryDetailView.

The Rb80CategoryList1View as shown in Figure 199 is not transaction-safe in terms of isolation (atomic/consistent/isolated/durable: ACID). The refresh changes objects in the most recent transaction and changes in that transaction show up simultaneously in the list (before any commit). The selected item in the list has sometimes another transaction as context than the sharedTransaction, and therefore the wrong object version is displayed in the detail view on a double-click.

2nd List ViewRb80CategoryList2View (Figure 200, left side) works with a transacted selectedItem and transactedcategoryHome, but its behavior is still not 100% transaction-safe in terms of isolation (ACID). The connection details are listed in Table 72 on page 315.

3rd List ViewRb80CategoryList3View (Figure 200, right side) seems to respect transactions.

312 Using VisualAge Smalltalk ObjectExtender

Figure 200. Rb80CategoryList2View and Rb80CategoryList3View Extracts

Page 339: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

A few script lines solve the problem:

allInstancesTrxSave: aHome

"Get allIInstances transaction save.Resume the current Transaction deferred."

| trxSave allInstances |

trxSave := Transaction current.

Transaction shared resume.allInstances := aHome allInstances.

[trxSave resume] abtDefer.

^allInstances

First, the current transaction is saved. Then, the read-only sharedTransaction context is resumed for performing the allInstances against the home. The previous transaction context is resumed with an abtDefer and the retrieved allInstances are returned. The connection details are listed in Table 73 on page 316.

An alternate implementation of the script would be the overriding of the allInstances of the home, or—less intrusive—an additional action in the public interface and an implementing method. A view part using the extended home would then again look like the Rb80CategoryList1View.

Nested Transactions 313

Page 340: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 71. Connections of the Rb80CategoryList1View

Source (S) Feature of S Target (T) Feature of T

12

CategoryDetailViewcategoryDetailView

instancetransactionCommittedOrRolledback

categoryDetailViewpbRefresh

selfclick

3 cnrCategories defaultActionRequested

CategoryDetailView new

4 (cnrCategories,defaultActionRequested --> CategoryDetailView,new)

normalResult categoryDetailView tempCategory

5 (cnrCategories,defaultActionRequested --> CategoryDetailView,new)

normalResult categoryDetailView openWidget

6 ( (cnrCategories,defaultActionRequested --> CategoryDetailView,new),normalResult --> categoryDetailView,tempCategory)

value cnrCategories selectedItem

7 pbNewRoot clicked CategoryDetailView new

8 (pbNewRoot,clicked --> CategoryDetailView,new)

normalResult categoryDetailView tempCategory

9 (pbNewRoot,clicked --> CategoryDetailView,new)

normalResult categoryDetailView openWidget

10 ( (pbNewRoot,clicked --> CategoryDetailView,new),normalResult --> categoryDetailView,tempCategory)

value categoryHome create

11 pbRefresh clicked cnrCategories items

12 (pbRefresh,clicked --> cnrCategories,items)

value categoryHome allInstances

13 sharedTransaction self CategoryDetailView parentTransact

314 Using VisualAge Smalltalk ObjectExtender

ion

14 Window aboutToOpenWidget

pbRefresh click

Page 341: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 72. Connections of the Rb80CategoryList2View

Source (S) Feature of S Target (T) Feature of T

12

CategoryDetailViewcategoryDetailView

instancetransactionCommittedOrRolledback

categoryDetailViewpbRefresh

selfclick

3 categoryHome self transactedCategoryHome

self

4 cnrCategories selectedItem selectedItem self

5 cnrCategories defaultActionRequested

CategoryDetailView new

6 (cnrCategories,defaultActionRequested --> CategoryDetailView,new)

normalResult categoryDetailView tempCategory

7 (cnrCategories,defaultActionRequested --> CategoryDetailView,new)

normalResult categoryDetailView openWidget

8 ( (cnrCategories,defaultActionRequested --> CategoryDetailView,new),normalResult --> categoryDetailView,tempCategory)

value selectedItem self

9 pbNewRoot clicked CategoryDetailView new

10 (pbNewRoot,clicked --> CategoryDetailView,new)

normalResult categoryDetailView tempCategory

11 (pbNewRoot,clicked --> CategoryDetailView,new)

normalResult categoryDetailView openWidget

12 ( (pbNewRoot,clicked --> CategoryDetailView,new),normalResult --> categoryDetailView,tempCategory)

value transactedCategoryHome

create

13 pbRefresh clicked cnrCategories items

Nested Transactions 315

14 (pbRefresh,clicked --> cnrCategories,items)

value transactedCategoryHome

allInstances

15 sharedTransaction self selectedItem transaction

16 sharedTransaction self CategoryDetailView parentTransaction

17 sharedTransaction self transactedCategoryHome

transaction

18 Window aboutToOpenWidget

pbRefresh click

Page 342: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 73. Connections of the Rb80CategoryList3View

Source (S) Feature of S Target (T) Feature of T

12

CategoryDetailViewcategoryDetailView

instancetransactionCommittedOrRolledback

categoryDetailViewpbRefresh

selfclick

3 cnrCategories selectedItem selectedItem self

4 cnrCategories defaultActionRequested

CategoryDetailView new

5 (cnrCategories,defaultActionRequested --> CategoryDetailView,new)

normalResult categoryDetailView tempCategory

6 (cnrCategories,defaultActionRequested --> CategoryDetailView,new)

normalResult categoryDetailView openWidget

7 ( (cnrCategories,defaultActionRequested --> CategoryDetailView,new),normalResult --> categoryDetailView,tempCategory)

value selectedItem self

8 pbNewRoot clicked CategoryDetailView new

9 (pbNewRoot,clicked --> CategoryDetailView,new)

normalResult categoryDetailView tempCategory

10 (pbNewRoot,clicked --> CategoryDetailView,new)

normalResult categoryDetailView openWidget

11 ( (pbNewRoot,clicked --> CategoryDetailView,new),normalResult --> categoryDetailView,tempCategory)

value categoryHome create

12 pbRefresh clicked Rb80CategoryList3View

allInstancesTrxSave:

13 (pbRefresh,clicked --> Rb80CategoryList3View,allInstancesTrxSave:)

normalResult cnrCategories items

316 Using VisualAge Smalltalk ObjectExtender

14 (pbRefresh,clicked --> Rb80CategoryList3View,allInstancesTrxSave:)

parameter1 categoryHome self

15 sharedTransaction self CategoryDetailView parentTransaction

16 sharedTransaction self selectedItem transaction

17 Window aboutToOpenWidget

pbRefresh click

Page 343: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

14.13.2 Category Detail ViewFigure 201 shows the Rb80CategoryDetailView in the Composition Editor with the connections listed in Table 74 on page 320 through Table 77 on page 323. Table 202 on page 318 shows the list and detail views at runtime. The trace in the System Transcript shows the database committed insert of Category C1.6 and the Category List 3 (All) refresh. The Category C1.7 is already committed to Category C1, but not yet to the database. Category C1 shows already Category C1.7 and hasModific(ation)s:, but not yet the List).

Nested Transactions 317

Figure 201. Rb80CategoryDetailView in Composition Editor

Page 344: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

318 Using VisualAge Smalltalk ObjectExtender

Figure 202. Rb80DetailView at Runtime

Page 345: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

For the subcategories list update on a commit of any next lower level of nested transactions (Connection 11), the new Rb99Signaller part is introduced. It knows the category transacted variable (valueHolder) with the business object (Connection 9) and a list of featureNames, which are set at edit time (Figure 203) to signalSelectedDependents with this method:

signalSelectedDependents

"Perform the signalSelectedDependents on transactedVariable (valueHolder) value in its context using the list of featureNames.First save the current transaction, afterwards resume it. featureNames isanOrderedCollection of Symbols to signal changes on thetransactedVariable value, using the pattern:

self signalEvent: #symbolwith: self symbol

where self is the value of the transactedVariable and symbol the getter for(mostly) (link) collections (because ObjectExtender does not update/event(link) collections automatically... with good performance reason."

| object trx saveTrx |saveTrx := Transaction current.(trx := self transactedVariable transaction) == nil ifTrue: [^self].trx resume.(object := transactedVariable value) == nil ifFalse: [

self featureNames do: [ :symbol |object signalEvent: symbol with: (object perform: symbol) ] ].

saveTrx resume

Nested Transactions 319

Figure 203. featureNames of signaller in Rb80DetailView

Page 346: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 74. Connections of the Rb80CategoryDetailView (Part 1 of 4)

Source (S) Feature of S Target (T) Feature of T

1 category transaction transaction self

2 category isNotPersistent categoryIdField enabled

3 category categoryId categoryIdField object

4 category categoryTitle categoryTitleField object

5 category isPersistent pbDeleteCategory enabled

6 category parentcategoryReferenceString

parentCategoryIdField object

7 category self CategoryDetailView tempParentcategory

8 category subcategories cnrSubcategories items

9 category valueHolder signaller transactedVariable

10 CategoryDetailView instance categoryDetailView self

11 categoryDetailView transactionCommitted

signaller signalSelectedDependents

12 categoryIdField object concat string1

13 categoryIsNew isTrue transaction rollback

14 categoryIsNew isFalse transaction rollback

15 (categoryIsNew,isFalse --> transaction,rollback)

normalResult junction junct

16 (categoryIsNew,isTrue --> transaction,rollback)

normalResult Window closeWidget

320 Using VisualAge Smalltalk ObjectExtender

17 categoryTitleField object concat string3

18 cnrSubcategories selectionIsValid pbDeleteSubcat enabled

19 cnrSubcategories defaultActionRequested

CategoryDetailView new

20 cnrSubcategories selectedItem selectedIItem self

21 cnrSubcategories items subcateogories self

Page 347: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 75. Connections of the Rb80CategoryDetailView (Part 2 of 4)

Source (S) Feature of S Target (T) Feature of T

22 (cnrSubcategories,defaultActionRequested --> CategoryDetailView,new)

normalResult categoryDetailView tempCategory

23 (cnrSubcategories,defaultActionRequested --> CategoryDetailView,new)

normalResult categoryDetailView openOwnedWidget

24 ( (cnrSubcategories,defaultActionRequested --> CategoryDetailView,new),normalResult --> categoryDetailView,tempCategory)

value selectedIItem self

25 concat string Window title

26 isTopLevelTransaction isTrue pbOKSave object

27 isTopLevelTransaction isFalse pbOKSave object

28 junction juncted parentTransaction self

29 (junction,juncted --> parentTransaction,self)

value parentTransaction self

30 parentcategoryIsNil isNil category parentcategory

31 (parentcategoryIsNil,isNil --> category,parentcategory)

value tempParentcategory self

32 parentTransaction self Rb80CategoryDetailView

parentTrx:

33 parentTransaction self transaction self

34 (parentTransaction,self --> value parentTransaction beginChild

Nested Transactions 321

transaction,self)

35 pbCancel clicked categoryIsNew check

36 (pbCancel,clicked --> categoryIsNew,check)

anObject category isNotPersistent

37 pbDeleteCategory clicked category remove

38 (pbDeleteCategory,clicked --> category,remove)

normalResult transaction commit

Page 348: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 76. Connections of the Rb80CategoryDetailView (Part 3 of 4)

Source (S) Feature of S Target (T) Feature of T

39 (pbDeleteCategory,clicked --> category,remove)

normalResult Window closeWidget

40 pbDeleteSubcat clicked selectedIItem remove

41 (pbDeleteSubcat,clicked --> selectedIItem,remove)

aCategory cnrSubcategories selectedItem

42 (pbDeleteSubcat,clicked --> selectedIItem,remove)

errorResult errorPrompter promptFor:

43 (pbDeleteSubcat,clicked --> selectedIItem,remove)

normalResult subcateogories remove:

44 ( (pbDeleteSubcat,clicked --> selectedIItem,remove),normalResult --> subcateogories,remove:)

anObject selectedIItem self

45 pbNewSubcat clicked CategoryDetailView new

46 (pbNewSubcat,clicked --> CategoryDetailView,new)

normalResult categoryDetailView tempCategory

47 (pbNewSubcat,clicked --> CategoryDetailView,new)

normalResult categoryDetailView openOwnedWidget

48 ( (pbNewSubcat,clicked --> CategoryDetailView,new),normalResult --> categoryDetailView,tempCategory)

value categoryHome create

49 pbOKSave clicked transaction commit

50 (pbOKSave,clicked --> transaction,commit)

normalResult junction junct

51 (pbOKSave,clicked --> errorResult junction junct

322 Using VisualAge Smalltalk ObjectExtender

transaction,commit)

52 Rb80CategoryDetailView TID trxIDField object

53 Rb80CategoryDetailView parentTID parentTrxIDField object

54 subcateogories isEmpty pbDeleteCategory enabled

55 transaction self Rb80CategoryDetailView

trx:

56 transaction self isTopLevelTransaction check

Page 349: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 77. Connections of the Rb80CategoryDetailView (Part 4 of 4)

Note: The zzInspectHotSpot on the Category Id label triggers the inspector through the inspect: script (Connection 66)) on the category business object (Connection 67) and is for test purposes only.

Source (S) Feature of S Target (T) Feature of T

57 transaction hasModifications tbHasModifications selection

58 transaction valueHolder CategoryDetailView parentTransaction

59 transaction self selectedIItem transaction

60 (transaction,self --> isTopLevelTransaction,check)

anObject transaction isTopLevel

61 Window aboutToOpenWidget

category self

62 Window aboutToOpenWidget

parentcategoryIsNil check

63 Window closedWidget transaction rollback

64 (Window,aboutToOpenWidget --> category,self)

value tempCategory self

65 (Window,aboutToOpenWidget --> parentcategoryIsNil,check)

anObject category parentcategory

66 zzInspectHotSpot clicked Rb80CategoryDetailView

inspect:

67 (zzInspectHotSpot,clicked --> Rb80CategoryDetailView,inspect:)

parameter1 category self

Nested Transactions 323

Page 350: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

324 Using VisualAge Smalltalk ObjectExtender

Page 351: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 15. Concurrent Transactions

In Chapter 14, “Nested Transactions” on page 283, we cover transactions in detail, focusing especially on nested transactions. However, there is another dimension to transactions, namely concurrence. A transaction can have many parallel child transactions, and there can be transactions in different processes or even on different machines working on the same objects at the same time. In this chapter we explain how you can handle some of the conflicts that come up in concurrent scenarios with ObjectExtender.

15.1 Isolation Policies

A transaction is essentially the management of resources over a period of time. Within a transaction, ObjectExtender keeps track of which objects are created, deleted, or modified. It also manages isolation of changes between transactions, so that changes within a transaction are not seen outside the scope of the transaction until it is committed.

ObjectExtender also supports optimistic (nonlocking) and pessimistic (locking) strategies on the back-end data store:

• Optimistic means that usually no collisions are anticipated, but any that occur will be dealt with. Locking and updating are deferred until the ObjectExtender transaction is committed. This is probably the appropriate strategy most of the time, because it allows you longer-lasting transactions without having locks or tying up other significant back-end resources.

• Pessimistic means that because you do not want to deal with collisions, resources are locked for exclusive use. If you have compelling reasons to use pessimistic locking, you can indicate this in the Map Browser for selected classes with Enable pessimistic locking. This causes different service code to be built; as a result, it is not possible to change the locking

© Copyright IBM Corp. 1999 325

strategy dynamically at run time.

What you can set at run time is the isolation policy for each transaction. The repeatable read isolation policy guarantees that if the same object is fetched multiple times within a transaction, the attribute values will always be the same. This is not the case with the unrepeatable read policy, where the attribute values of a business object are not affected by uncommitted changes in sibling transactions. However, if the sibling transaction commits before the current transaction, changes made in the sibling may become visible in the current transaction.

Page 352: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

15.2 Optimistic Locking

If you do not specify any particular isolation policy, what you get is a nonlocking implementation of repeatable read. This can also be called copy-on-read, because a copy of the data of a business object is made the first time it is read in a transaction. Each subsequent operation on the object in that transaction, whether read or write, is then performed on the copy.

As soon as the transaction is committed, any changes to the object are written to the version of the object in the parent transaction, or to the data store, if a top-level transaction is being committed. At this time, however, the attribute values of the object in the parent transaction, or in the data store, might be different from those that were copied-on-read. A sibling transaction or another top-level transaction might have committed its changes in the meantime. This kind of situation is called collision.

15.2.1 Collision Detection in the ImageIn Chapter 11, “Many-to-Many Associations” on page 241, we have two windows for working with titles: one contains a list of all titles, the second is opened for editing a selected title. Nothing prevents you from having more than one detail view on a title. Because we have only one top-level transaction, however, all detail windows show and work on the same version of the object. As a result, a change in one window is reflected everywhere.

That may not always be the desired behavior in your applications. You may not want to see any changes you make in one window anywhere else, unless you click an OK or Apply button. Furthermore, you may want to allow the user to discard attempted changes altogether. As Chapter 14, “Nested Transactions” on page 283 shows, the way to do that is with nested transactions.

For the present example, we again strip down the application to the

326 Using VisualAge Smalltalk ObjectExtender

minimum. We ignore the association of titles to categories and work only with titles and their attributes. But we do add a nested transaction for each details window.

To follow us through this example, once you have defined the necessary model, schema, and mapping for Title, with the same attributes and columns as in Chapter 11, “Many-to-Many Associations” on page 241, you can advance to constructing the Rb90TitleView part with the help of Figure 204 and Table 78 on page 329.

Page 353: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 204. Rb90TitleView

Rb90TitleView is not much different from Rb50TitleView, except for:

• A new OK button, which explicitly triggers a commit on the top-level transaction. Triggering is no longer done as a reaction to events from the

Concurrent Transactions 327

secondary window.

• A transacted variable for the title home, whose transaction attribute is connected to the top-level transaction.

• A message prompter for displaying errors that occur when committing the top-level transaction. The prompter informs us about collisions.

• The parameter that is passed to the secondary window is no longer self of transacted title, but valueHolder. So what we are really passing is the variable with contents, not the contents alone.

Page 354: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

This last change needs more explanation. When you construct the Rb90TitleDetailsView part (Figure 205 on page 330), a transacted variable for the selected title is also contained. As a result, we could connect the transacted title in Rb90TitleView and the transacted title in Rb90TitleDetailsView. Because we want a nested transaction for each secondary window, the transacted variable in Rb90TitleDetailsView needs to be connected to the new child transaction created when the window is opened.

This works fine when we edit an existing title, but when we create a new title and open the detail window for editing it, the Rb90TitleDetailsView part’s initialization order makes a significant difference. Parameters passed to the factory of a part are set at creation time, before the start of any event handling within the part. The transacted title is set before the new child transaction is created in the new part. The result of the beginChild action, which is triggered by the openedWidget event, is then assigned to the transaction attribute of the transacted title. This change of transactions for a transacted variable works if the variable holds an existing object. However, it does not work if it holds a new object. Therefore we need to create the child transaction, assign it to the transaction attribute of the transacted variable, and then set the contents of the variable.

However, the right order of initialization is only the first part of the story. We could have managed to achieve that by passing both the top-level transaction and the transacted variable to Rb90TitleDetailsView. Instead, we chose to import the transacted variable as a whole, thus having a variable of a transacted variable in the secondary part. The advantage of this peculiar solution is that we do not need to pass the top-level transaction separately, because it is an attribute of the AbtTransactedVariable.

328 Using VisualAge Smalltalk ObjectExtender

Page 355: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 78. Connections of Rb90TitleView

Source (S) Feature of S Target (T) Feature of T

1 titleContainer defaultActionRequested editButton click

2 titleContainer selectionIsValids editButton enabled

3 titleContainer selectionIsValids deleteButton enabled

4 newButton clicked transacted titleHome create

5 (newButton,clicked --> transacted titleHome,create)

normalResult transacted title self

6 newButton clicked editButton click

7 editButton clicked Rb90TitleDetailsView new

8 Rb90TitleDetailsView instance titleDetailsView self

9 editButton clicked titleDetailsView openWidget

10 Window openedWidget sharedTransaction beginChild

11 (Window,openedWidget --> sharedTransaction,beginChild)

normalResult topLevelTransaction self

12 deleteButton clicked transacted title remove

13 deleteButton clicked topLevelTransaction commit

14 okButton clicked topLevelTransaction commit

15 (okButton,clicked --> topLevelTransaction,commit)

errorResult commitErrorPrompter promptFor:

16 (deleteButton,clicked --> topLevelTransaction,commit)

errorResult commitErrorPrompter promptFor:

17 topLevelTransaction committed sharedTransaction beginChild

18 (topLevelTransaction,committed --> sharedTransaction,beginChild)

normalResult topLevelTransaction self

Concurrent Transactions 329

19 transacted title transaction topLevelTransaction self

20 Window closedWidget topLevelTransaction rollback

21 titleHome self transacted titleHome self

22 topLevelTransaction self transacted titleHome transaction

23 titleContainer selectedItem transacted title self

24 transacted title valueHolder Rb90TitleDetailsView valueHolderVariable

25 transacted titleHome allInstances titleContainer items

Page 356: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

The other details of the Rb90TitleDetailsView part are shown in Figure 205 and Table 79.

Figure 205. Rb90TitleDetailsView

The major differences from the Rb50TitleDetailsView are:

• There are no more lists and buttons to work with the title’s categories.

• All activity related to the nested transaction has been added.

330 Using VisualAge Smalltalk ObjectExtender

A message prompter displays any errors that occur when the nested transaction is committed.

Page 357: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 79. Connections of Rb90TitleDetailsView

Source (S) Feature of S Target (T) Feature of T

1 okButton clicked childTransaction commit

2 cancelButton clicked childTransaction rollback

3 transacted titleVariable isbnNumber isbnNumberField object

4 transacted titleVariable isNotPersistent isbnNumberField enabled

5 transacted titleVariable author authorField object

6 transacted titleVariable publisher publisherField object

7 transacted titleVariable description descriptionField object

8 Window openedWidget isbnNumberField setFocus

9 Window openedWidget parentTransaction beginChild

10 (Window,openedWidget --> parentTransaction,beginChild)

normalResult childTransaction self

11 childTransaction committedOrRolledback

Window closeWidget

12 (okButton,clicked --> childTransaction,commit)

errorResult commitFailedPrompter

promptFor:

13 (Window,openedWidget --> parentTransaction,beginChild)

normalResult transacted titleVariable

transaction

14 (Window,openedWidget --> parentTransaction,beginChild)

normalResult transacted titleVariable

self

16 ( ( (Window,openedWidget --> parentTransaction,beginChild),normalResult --> transacted titleVariable,self),value -->

parameter1 valueHolderVariable

self

Concurrent Transactions 331

Now we are ready to address the central issue of this chapter: What happens when we make changes to one title in two different windows concurrently? Try it out. What you should see when you commit is a message box like that in Figure 206 as soon as you commit the second nested transaction (that is, click the OK button).

Rb90TitleDetailsView,fromValueHolder:)

17 valueHolderVariable transaction parentTransaction self

Page 358: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 206. Collision Detection in Sibling Nested Transactions

This tells you that, since the first nested transaction has already committed its changes, it is no longer possible to commit the changes in the second nested transaction to the parent top-level transaction. This is what is called collision detection. In a real world application, you would either display an instructional message to the user or implement your own collision resolution.

To implement your own strategy, you could use commitWhenFailureDo: and do whatever you want to do in the exception block, or you could override the canMerge:with: and merge:with: methods in the business object. In your implementation of canMerge:with:, you could check the conditions when you want to merge the parent and child versions of the business object, which are passed as parameters to that method. The default return value is false. In merge:with: you can actually perform the merging (the default implementation is copying the child to the parent). If, for example, you want to have a "last wins" behavior, you could always return true for canMerge:with:.

15.2.2 Collision Detection on the Back-End Data StoreNow what happens if you have two Rb90TitleView windows and change the same title in their respective subwindows? Well, nothing special. As soon as you commit one top-level transaction (by clicking the OK button on the Rb90TitleView), the changes cause an update to the database. The same

332 Using VisualAge Smalltalk ObjectExtender

happens when you commit the second top-level transaction. So normally the last committing transaction "wins."

If you want the same behavior as with concurrent nested transactions for concurrent top-level transactions, let the data store do the collision detection. Normally, the SQL update statements generated by ObjectExtender use the primary key in the WHERE clause to identify the row to be updated. In the Map Browser, however, you can specify attributes to Be part of optimistic predicate. That means that the WHERE clause is enhanced by additional expressions to identify the row. When a top-level transaction is committed,

Page 359: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

ObjectExtender fills these expressions with the attribute values that were read from the database before the object was changed, as is symbolically shown in the following SQL statement:

UPDATE TableName SET key = keyValue, attribute = newAttributeValue, ...WHERE (key = keyValue) AND (attribute = oldAttributeValue)

When the row is not changed during the transaction, that means no other top-level transaction has changed the corresponding object, and the database finds the right row to be updated. If, however, the row (to be precise, the optimistic predicate attribute) was changed in the meantime, the database can no longer find a row to update and reports an SQL error. This error is then transferred by ObjectExtender to your application so you can deal with it.

Thus, if you want collision detection between top-level transactions, whether they run in the same process or not, you must specify an optimistic predicate. It can be either any set of business object attributes, if your business logic requires that, or a special nonbusiness attribute such as a time stamp or a version number.

We have no sensible business requirement for a time stamp or version number, but there is an easy way to try out this method of collision detection. Mark an attribute—for example, author—as part of the optimistic predicate (do not forget to regenerate the service code) and perform a Global ObjectExtender Reset. When you then open two Rb90TitleViews and change the same title in their subviews, you should get an error message when the second top-level transaction is committed (if you use DB2 the error message looks like this:

"[SQLSTATE=02000 - [IBM][CLI Driver][DB2/2] SQL0100W No row was found for FETCH, UPDATE or DELETE; or the result of a query is an empty table. [Native Error=100])."

Again, you can use the exception block of commitWhenFailureDo: to perform

Concurrent Transactions 333

the collision resolution or inform the user in intelligible words.

You have to do a bit more to introduce nonbusiness attributes, such as a version number or a time stamp. Besides adding an attribute to the model and a column to the schema, you need to add code that increments the version number or sets the time stamp just before you commit the transaction. Setting the time stamp from Smalltalk bears the risk (admittedly slight) that you could have the same exact time stamp on different machines.

Page 360: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Another way to introduce nonbusiness attributes is to use database time stamps. Although this approach involves changing generated code, you can change the SQL strings in the query pool so that they use CURRENT TIMESTAMP, which returns the current database time stamp. As a result, when you add a timestamp attribute to our Title model and a timestamp column to the schema (the standard time stamp size is 26 characters), mark the timestamp attribute as being part of the optimistic predicate, generate all the necessary code, and change the insertSqlString and updateSqlString methods from:

insertSqlString

"Return the SQL string for the query called insert"

^’INSERT INTO USERID.Rb90Title ( isbnNumber, author, description, publisher, timestamp )

VALUES ( :isbnNumber, :author, :description, :publisher, :timestamp ) ’

updateSqlString

"Return the SQL string for the query called update"

^’UPDATE USERID.Rb90Title SET author = :author, description = :description, publisher = :publisher, timestamp = :timestamp

WHERE (isbnNumber = :isbnNumber) AND (timestamp = :V1)’

to:

insertSqlString

"Return the SQL string for the query called insert"

^’INSERT INTO USERID.Rb90Title ( isbnNumber, author, description,

334 Using VisualAge Smalltalk ObjectExtender

publisher, timestamp ) VALUES ( :isbnNumber, :author, :description, :publisher,

CURRENT TIMESTAMP ) ’

updateSqlString

"Return the SQL string for the query called update"

Page 361: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

^’UPDATE USERID.Rb90Title SET author = :author, description = :description, publisher = :publisher, timestamp = CURRENT TIMESTAMP

WHERE (isbnNumber = :isbnNumber) AND (timestamp = :V1)’

Because you took away host variables in the SQL query string ObjectExtender intended to fill, you must remove the timestamp attribute from the list of attributes to be written. If you do not, you get an error message ("Input argument size does not match query string") on commit. The list of data attributes is assembled in the ...Data and ...UpdateData methods of the data object (where the ellipses stand for the class name), so you have to remove the line for timestamp and reduce the array size by 1.

15.3 Pessimistic Locking

With the optimistic scenarios we have discussed so far, collisions are detected when the transactions are committed and changes written to the database. Pessimistic strategies avoid collisions altogether by apparently locking resources for exclusive use. There are no collisions when writing data, but they may occur when trying to acquire a lock. Trying to acquire a lock may be done explicitly by the application programmer or implicitly by ObjectExtender.

If you tell ObjectExtender to generate locking implementations for the service code for (some of) your classes and your transaction is set to support repeatable reads, ObjectExtender implicitly tries to procure a lock when an object is read (lock-on-read). If the transaction’s isolation policy is unrepeatable reads, an attempt to acquire a lock is automatic when an object is changed (lock-on-write).

Your code must take care of exceptions that are raised if an object is already locked. For instance, if you use allInstances within a transaction with a repeatable read strategy, add:

Concurrent Transactions 335

Transaction begin.[ titles := Rb90TitleHome singleton allInstances ]

when: #ExVapObjectLockeddo: [ :aSignal | "Notify the user that an object is locked" ]

Regardless of the transaction’s isolation policy, you can try to explicitly lock an object:

[ title lock ]when: #ExVapObjectLockeddo: [ :aSignal | "Notify the user that the object is locked" ]

Page 362: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

15.4 Summary of Transaction Characteristics

The characteristics of transactions are as follows:

• Whenever a transaction is created, it becomes the current transaction.

• Whenever a transaction is committed or rolled back, its parent transaction becomes the current transaction.

• When a transaction is committed, all of its child transactions are also committed.

• A transacted variable part will ensure that its contents are always accessed in the context of its specified transaction, but it will not change the current transaction.

• Changes to objects in top-level transactions are committed to the data store.

• Changes to objects in nested transactions are committed to the parent transaction.

• The isolation policy implemented in the home collections can be either optimistic (nonlocking) or pessimistic (locking). The policy cannot be changed at run time.

• The isolation policy for a transaction can be either repeatable read (copy/lock-on-read) or nonrepeatable read (copy/lock-on-write). It can be changed at run time.

• Collision detection between sibling nested transactions is done automatically by ObjectExtender.

• Collision detection between top-level transactions is done through the database by telling ObjectExtender to use optimistic predicates.

336 Using VisualAge Smalltalk ObjectExtender

Page 363: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 16. Binary Large Objects

This chapter is a short excursion into binary large objects (BLOBs), a subject that is not directly related to ObjectExtender but sets the scene for Chapter 17, “Lite Collections” on page 341.

A BLOB is a database data type for varying-length strings measured in bytes that can be as large as 2+ GB (2 147 483 647 bytes). A BLOB is primarily intended to hold nontraditional data such as pictures, voice, and mixed media. Another use is to hold structured data for exploitation by user-defined types and functions.

In the example in Chapter 17, “Lite Collections” on page 341, we store pictures in BLOBs. One standard for the definition of pictures is the graphics interchange format (GIF), and that is the one we want to adhere to. In this chapter we describe the construction of a nonvisual part that can hold a GIF image, read a GIF image from a file, display the image in a window, and make the necessary conversions to and from strings. ObjectExtender can then store these strings as BLOBs in the database.

16.1 Create a New Part Named GifImage

To create the new part, select an existing application or create a new one (we created a new application called Rb10GifImage) in the VisualAge Organizer. In the dialog that follows after you select Parts->New..., enter the part name (we chose GifImage) and be sure that the part type is set to Nonvisual part. We use this part type because we want the part to be usable in all situations, whether a user interface is involved or not.

16.2 Define the Part’s Public Interface

The part’s public interface is that subset of the whole class functionality that

© Copyright IBM Corp. 1999 337

is visible when parts are plugged together in the Composition Editor. To define the public interface, use the Public Interface Editor.

We want the GifImage part to interact with three other parts:

• We want to be able to read an image from a GIF file. Therefore we define an action called contentsFromGifFile (action selector: contentsFromGifFile:), which takes a string holding the file’s path and name as a parameter.

Page 364: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

• Most of the time the image the part holds must be displayed somewhere. An attribute called displayWindow serves that purpose.

• Last but not least, we want the GifImage part to be able to build its image from a string and, in the other direction, convert the image back to a string. That is why we define an attribute called imageAsString with a get selector imageAsString and a set selector contentsFromString:. The change event symbol is also imageAsString, and the attribute data type is String.

When the public interface is defined, File->Generate Default Scripts can be used to create implementation skeletons. Select all the selectors but be sure not to select imageAsString in the instance variable list box, because we do not want an instance variable for that; we only want the part to behave as if it had an instance variable. Click Generate Selected to continue.

16.3 Provide the Part’s Implementation

Once you have defined the interface, the next step is the implementation. As mentioned, what the part is intended to hold—but what we did not make public—is an image called a CgDeviceIndependentImage. Therefore, an instance variable called image, with its private getter image and private setter image:, needs to be defined.

Remember that we are working on a part. Therefore we have to ensure that our part does what is expected from a part: that is, it notifies other interested parts of changes to its public attribute values. So we have to add the required code in the image: setter method. Note we do not notify others of a change in image, because that is not visible to the outside world, but rather we notify of a change in what we provide to other parts: imageAsString. The script is:

image: aCgDeviceIndependentImage

338 Using VisualAge Smalltalk ObjectExtender

"Private - Save the value of image."

image := aCgDeviceIndependentImage.self signalEvent: #imageAsString

with: self imageAsString

The implementation for contentsFromGifFile:, which reads an image from a GIF file, looks like this:

Page 365: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

contentsFromGifFile: path

"Sets the receiver’s contents with the data from theGIF file specified by path."

self image: ( CgGIFFileFormat newloadFromFile: path;yourself ).

self displayImage

The contentsFromGifFile: method calls as its last statement the private method displayImage that draws the image on the window associated with the part:

displayImage

"Private - Displays the image on the associated window"

self displayWindow isNil ifFalse: [self image isNil ifTrue: [

self displayWindow primaryWidget window clearWindow ] ifFalse: [

self displayWindow primaryWidget windowputDeviceIndependentImage: CgGC default image: self imagesrcRect: (0@0 extent: self image extent)destRect: (0@0 extent: self image extent) ] ]

Binary Large Objects 339

The most interesting methods for us, however, are those that perform the conversion to and from strings. The easier direction is building the image from a string. As in contentsFromGifFile:, the essential work is done by an instance method of CgGIFFileFormat:

contentsFromString: aString

"Builds the receiver’s image from aString."

aString isNil ifTrue: [

Page 366: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

self image: nil ]ifFalse: [

self image: ( CgGIFFileFormat newloadFromByteObjects: (Array with: aString) offsetsIntoByteObjects: (Array with: 0)yourself ) ].

self displayImage

The conversion from the image to a string is a bit more complicated. We build an array of ByteArrays, which is then filled from a method in CgGIFFileFormat again. The filled arrays must then be flattened again into a string:

imageAsString

"Answers the image as a string"

| gifFileFormat imageSize byteArrays offsets ws |

self image isNil ifTrue: [^nil].

gifFileFormat := CgGIFFileFormat new.imageSize := gifFileFormat totalSizeBeforeUnload: self image.

byteArrays := OrderedCollection new.byteArrays add: (ByteArray new: imageSize).byteArrays := byteArrays asArray.offsets := Array with: 0.

( gifFileFormatunload: imageintoByteObjects: byteArrays

340 Using VisualAge Smalltalk ObjectExtender

offsetsIntoByteObjects: offsets ) ifFalse: [self error: gifFileFormat currentErrorString ].

ws := WriteStream on: ByteArray new.byteArrays do: [ :each | ws nextPutAll: each].

^ws contents

With this part, we are now ready to plunge right back into ObjectExtender issues; Lite Collections are next.

Page 367: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Chapter 17. Lite Collections

Lite Collections are useful for retrieving a subset of the information from a particular object in the database without instantiating every object that is retrieved. This feature can allow you to tune performance: For example, when building views to display different parts of the model, you can load the necessary information for a particular view only, and "drill deeper" as needed. Lite Collections can be thought of as a way of filtering an object that might have many attributes not applicable in a given context.

Imagine that we want to enhance the Employee example with photos of the employees. Considering the size of pictures stored in the database as BLOBs for that purpose, methods such as allInstances in the home collections, which retrieve all the data for every object, would take a very long time. With the help of Lite Collections, we therefore retrieve a list of employees with their text data only and load the picture of the selected employee on demand.

17.1 Define Model, Schema, and Mapping

For the sake of simplicity, we want to keep the model very lean. The Employee class needs only the attributes listed in Table 80. It is worth noticing that String is the type to use for holding things that are stored to the database as BLOBs—in this example, the picture of the employee.

Table 80. Attributes of Class Rb11Employee

Attribute Name Attribute Type Required

empNo String Yes (Object ID)

firstName String No

lastName String No

picture String No

© Copyright IBM Corp. 1999 341

It is in the Class Editor where not only attributes but also Lite Collections are defined. Figure 207 shows how a Lite Collection encompassing only the empNo, firstName, and lastName attributes are defined. We chose here not to use any filtering (that is, being able to select objects on the value of a filter property), or packeting (that is, reading only subsets of large result sets one at a time from the database).

Page 368: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 207. Definition of a Lite Collection for Rb11Employee

As far as defining the schema is concerned, the only thing out of the ordinary is the specification of the database type for picture: BLOB. We set the maximum length (in bytes) to 50,000, because the GIF images we stored as BLOBs had about that size. You can adjust the length to meet your needs.

Mapping is straightforward, but there is one point to observe: select Generate static Queries in the Generation Options dialog before you

342 Using VisualAge Smalltalk ObjectExtender

generate your service code! The interface between VisualAge Smalltalk and DB2 cannot currently handle dynamic SQL calls of the size that results from working with BLOBs. It is not necessary, however, to precompile the SQL statements as static; choosing the static flavor in ObjectExtender is enough.

17.2 Create a View with a Lite Collection

To illustrate the workings of Lite Collections, we use a visual part consisting of a container and two buttons, as shown in Figure 208. For full details on the connections, see Table 81.

Page 369: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 208. Rb11EmployeeView Part

The container holds and displays the Lite Collection of the employees without their pictures. The contents of the part are set to the result of the getEmployeeWithoutPictureLiteCollection action of the employeeHome, which has been generated as a consequence of the definition of the Lite Collection beforehand (see Connections 1 and 2 in Table 81 on page 344). Be aware that the Lite Collection holds only mere data objects, not the entire business objects. Later, we show how to get the respective business objects from the

Lite Collections 343

data objects.

We use the Refresh button as the focal point for the getEmployeeWithoutPicture action, which can be triggered by either the openedWidget event, the topLevelTransactionCommitted event of the details view, or the button’s click event. This technique helps to reduce clutter, and we use it, too, to open the details view of the selected employee by a click on

Page 370: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

the Edit employee button as well as by a double-click on the selected employee in the container.

Table 81. Connections of Rb11EmployeeView

To be able to open detail views on more than one employee at a time, we use a factory to create the Rb11EmployeeDetailsViews. We pass the selected employee data object to the factory, so that, after the view is created, the data object variable promoted from there is correctly initialized automatically.

When you first run this part, you are likely to find that the container does not show the employee information. Because the generated data object access

Source (S) Feature of S Target (T) Feature of T

1 refreshButton clicked employeeHome getEmployeeWithoutPictureLiteCollection

2 (refreshButton,clicked --> employeeHome,getEmployeeWithoutPictureLiteCollection)

normalResult liteCollectionContainer items

3 Rb11EmployeeDetailsView employeeDataObject liteCollectionContainer selectedItem

4 liteCollectionContainer defaultActionRequested editEmployeeButton click

5 editEmployeeButton clicked Rb11EmployeeDetailsView

new

6 detailsView topLevelTransactionCommitted

refreshButton click

7 Window openedWidget refreshButton click

8 Rb11EmployeeDetailsView instance detailsView self

9 editEmployeeButton clicked detailsView openWidget

344 Using VisualAge Smalltalk ObjectExtender

methods look up the attribute values in dictionaries with the attribute names as keys. The lookup is done with the all upper-case database column names, but the keys in the dictionaries are the mixed-case column names. The first idea for a workaround would be to enter all upper-case physical column names in the Schema Browser, but that causes an error during service code generation. A way to make it work is to patch the fieldNames class method, Rb11EmployeeRb11EmployeeDataObject, in the data object class, so that the strings are all upper case there.

Page 371: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

17.3 Create a View with a BLOB

Figure 209 on page 347 shows the Rb11EmployeeDetailView.

The view contains a form to display the employee’s picture stored in the database and a user interface to load a picture from a file for the displayed employee and store it in the database.

Two things are of particular interest in the EmployeeDetailsView part that is opened by the Employee Lite Collection window:

• We have a transacted variable for an employee business object, which is initialized from businessObject of the data object variable. The data object variable is promoted and set from outside. Calling the getBusinessObject method on a data object causes the real business object to be built, if necessary by issuing the respective SQL queries behind the scenes. In our case, the retrieval of the entire employee business object including the picture is triggered (Connections 7 and 8 in Table 82), causing the expected short delay. We cannot have an attribute-to-attribute connection from the data object to the business object, because that would provoke an immediate load of the complete business object as soon as the data object is loaded.

• The retrieved data is then displayed in the corresponding fields. The picture is handled with the help of the GifImage part we defined in Chapter 16, “Binary Large Objects” on page 337. The image is automatically converted from the string in the picture attribute of Employee to the internal GIF representation by contentsFromString: and asString in GifImage, the methods behind the attribute-to-attribute connection, Connection 4. Because of Connection 5 to the Form part, the GifImage knows where to display itself. The other direction of conversion is demonstrated by Connection 9 from the Load image from file button to the GifImage. As soon as the image is loaded from the file by contentsFromGifFile: in GifImage, the image is at once converted to a

Lite Collections 345

string and the string is stored in the Employee’s picture attribute.

Table 82 provides the full documentation for the connections in the EmployeeDetailsView part.

Page 372: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 82. Connections of Rb11EmployeeDetailsView

Source (S) Feature of S Target (T) Feature of T

1234

employeeBusinessObjectemployeeBusinessObjectemployeeBusinessObjectemployeeBusinessObject

empNofirstNamelastNamepicture

empNoFieldfirstNameFieldlastNameFieldgifImage

objectobjectobjectimageAsString

5 Form self gifImage displayWindow

6 Rb11EmployeeDetailsView openedWidget sharedTransaction beginChild

7 Rb11EmployeeDetailsView openedWidget employeeBusinessObject

self

8 (Rb11EmployeeDetailsView,openedWidget --> employeeBusinessObject,self)

value employeeDataObject businessObject

9 LoadImageFromFileButton clicked gifImage contentsFromGifFile

10 (LoadImageFromFileButton,clicked --> gifImage,contentsFromGifFile)

path pathField object

11 OKButton clicked topLevelTransaction commit

12 OKButton clicked Window closeWidget

13 (Rb11EmployeeDetailsView,openedWidget --> sharedTransaction,beginChild)

normalResult topLevelTransaction self

14 topLevelTransaction committedOrRolledback

sharedTransaction beginChild

15 (topLevelTransaction,committedOrRolledback --> sharedTransaction,beginChild)

normalResult topLevelTransaction self

346 Using VisualAge Smalltalk ObjectExtender

16 topLevelTransaction self employeeBusinessObject

transaction

17 CancelButton clicked topLevelTransaction rollback

18 CancelButton clicked Window closeWidget

Page 373: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 209. Rb11EmployeeDetailsView

Lite Collections 347

Page 374: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

348 Using VisualAge Smalltalk ObjectExtender

Page 375: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Appendixes

© Copyright IBM Corp. 1999 349

Page 376: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

350 Using VisualAge Smalltalk ObjectExtender

Page 377: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Appendix A. Overview of the Examples in This Book

Table 83 lists all examples used in this book. The example names are used as the project names to build the component names required and created by ObjectExtender. The naming conventions for the components are listed in Table 84 on page 353.

Table 83. Overview of Sample Applications in This Book

Example/Project Name Description

Rb20Employee Employee Example Top-Down (nothing given)

Rb21Employee Employee Example Bottom-Up(legacy database)

Rb30 EmpDept Employee and Department Example Top-Down

Rb31EmpDept Employee and Department Example Bottom-Up

Rb30EmpDeptRb31EmpDept Employee and Department ExampleOutside-In

Rb50Library Library Example: M-to-M-Relationships

Rb61Library Library Example: Inheritance - Single Table Mapping

Rb62Library Library Example: Inheritance - Multiple Table Mapping

Rb80Library Library Example: Nested Transactions

Rb90Library Library Example: Concurrent Transactions

Rb10GifImage Part for GIF Images

Rb11Employee Employee Example with Pictures

© Copyright IBM Corp. 1999 351

Page 378: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

352 Using VisualAge Smalltalk ObjectExtender

Page 379: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Appendix B. Naming Conventions

Table 84 shows the naming conventions used in this book for the components created and required by ObjectExtender. The starting point is always the project name, to which various suffixes are added. The rightmost column shows the resulting names of the classes generated by ObjectExtender. The project names are derived from the example names, which are listed in Table 83 on page 351.

Table 84. Naming Conventions

Element Name Applications Classes

D Model[Metamodel]

Project Project+ModelApp[Project+MetamodelApp]

Project+Model[Project+Metamodel]

R Real Class[Model]

Project+App[Project+ModelApp]

ClassClass+HomeClass+KeyClass+To+Role+Relationship

D Map Project(Model+Schema)

Project+MapApp(Model+Schema+MapApp)

Project+Map(Model+Schema+Map)

D Schema Project Project+SchemaApp Project+Schema

R Services Project+ServicesApp(Model+Schema+ServicesApp)

Project+Services(Model+Schema+Services)

R Datastore Project+DataStore(Model+Schema+DataStore)

R Helpers Project+Class+DataObjectProject+Class+ExtractorProject+Class+InjectorProject+Class+QueryPool

© Copyright IBM Corp. 1999 353

Project+Class+ServiceObject(Model+Schema+DataObject)(Model+Schema+Extractor)(Model+Schema+Injector)(Model+Schema+QueryPool)(Model+Schema+ServiceObject)

- (when generated)- D=Development-time-only elements—have a name and an application and class- R=Runtime elements—have no name, just an application and class- [Alternative], when the Model name suffix is used to differentiate the classes in a Model-View-Controller

(MVC) context. See also Note below this table.

Page 380: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Note: For situations—not unusual in Smalltalk—where the project name is the same as the class name: For some names ObjectExtender suggests defaults. For the application where the generated model class code is stored, for example, ObjectExtender suggests the name built from the model name, for example, Rb20Employee, with ModelApp as suffix. Now, if you name your application where you store the model—actually the model definition—with suffix ModelApp, this very application will then by default also be the storage of the generated code. But at runtime the model definitions and all of the ObjectExtender development time prerequisites, such as the classes in VapMetadataApp, are nor longer needed. Therefore, if you want to use ObjectExtender’s default application naming (and the Model View Controller (MVC) kind of application name suffixing) but do not want the metadata overhead at runtime (or packaging), we suggest that you use the alternative naming for the model definitions, such as MetamodelApp and Metamodel for the storage application and class, respectively. Otherwise, you have to change the Model Code Generation Options before the first generation by changing the model application name suffix from ModelApp to just App (see for example, 5.2.1, “Set Model Code Generation Options” on page 54).

ObjectExtender sets automatically the VapMetadataApp as metadata prerequisite for all metadata storage applications. For lean packaging and runtime systems we suggest to store the generated model and services code never together in the same applications as the model, schema, and map.

Whenever you get an error message like this:

Class creation failure: Rb20EmployeeDataStore cannot change its superclass to AbtDataStore because it is not visible to Rb20EmployeeServicesApp.

you mixed up some names by reusing them. This may happen, for example when you keep—not unload—the services application generated for the local image data store and try to generate the services for the database from a map with the same name as the model.

354 Using VisualAge Smalltalk ObjectExtender

Page 381: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Appendix C. Downloadables, ConfigMaps, Applications

This appendix supplies information about the downloables files (Table 85 on page 356), selective configuration maps (Table 86 on page 357 and Table 87 on page 357), and two configuration maps with all applications and classes (Table 88 on page 358 through Table 91 on page 360).

© Copyright IBM Corp. 1999 355

Page 382: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 85. Downloadable File RBOE.zip and Its Contents

No. File(s)(Contents [Size])

Description

0 SG245258.zip(zip)

The actual downladable zip file containing all zipped files.

1 aaRead.txt(text/workspace)

Information about the contents of the SG245258.zip file, including late breaking news.

2 RBOED.dat(libary)

Contains all configuration maps and applications and classes which are built in this book, some other samples, and some ObjectExtender supporting stuff (enabled browser, enhanced physical name building support,...). Contains:Rb00ConfigMap for full import/export; C01, C02, C03, C04, C05, C98 and C99 config maps for application oriented import/export and loading.

3 RBOEZD.dat(libary)

Contains the configuration map with changes to ObjectExtender. Import and browse changes first, then load selectively on demand... (Rb01ConfigMap)

4 Rb1to1OW.wsp(text/workspace)

Workspace with test scripts, zap, and transcript output of the detailed 1:1/non-required sample in theRb1to1App

5 Rb1MSROW.wsp(text/workspace)

Workspace with test scripts, zap, and transcript output of the detailed 1:Many/Self referencing Required sample in the Rb1toMselfReqApp.

6 Rb20DBCR.txt(text)

Report of the DB Rb20Employee table and key creation

7 Rb20EmpL.lis(local image datastore)

Save of a local image data store containing one Rb20Employee instance

8 Rb20HDLW.wsp(text/workspace)

Workspace to run the Rb20... sample with scripts headless

9 Rb20LISW.wsp(text/workspace )

Workspace script sequence to verify the local image schema and data store generation

10 Rb50TstW.wsp Workspace to test M-to-M associations.

356 Using VisualAge Smalltalk ObjectExtender

(text/workspace )

11 Rb6XTstW.wsp(text/workspace )

Workspace to test inheritance.

12 Rb70TstW.wsp(text/workspace )

Workspace to test selective queries.

13 Rb90TstW.wsp(text/workspace )

Workspace to test transaction concurrence.

14 RbBlob(XX).jpg(gif BLOBs)

Gif BLOBs to test BLOBs and Lite Collections.(XX)= B2[416KB], BK[31KB], DS[31KB], MM[36KB], PB[30KB], UB[33KB]

Page 383: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 86. Application Configuration Maps

ID ConfigMap Name (Prerequisites) Description [Applications ( Prereqs) | Applications (Prereqs) ]

C01 Rb20EmployeeLISConfigMap (LC99) Everything to run the Employee - Top-Down sample with a local image data store—requires no database—and with a GUI. It is a nice sample for a stand-alone application. Load and run It! Note: LC99 means that C99 must be loaded first.

A01 Rb20EmployeeModelAppA02 Rb20EmployeeApp

A03 Rb20EmployeeServicesApp (A02)A04 Rb20EmployeeViewLISApp (A02 A03 A99)

C02 Rb20EmployeeDBConfigMap (LC99). Everything to run the Employee - Top-Down sample with the database image store—requires DB2, GUI, and Transaction samples.

A01 Rb20EmployeeModelAppA02 Rb20EmployeeAppA05 Rb20EmployeeMapApp

A06 Rb20EmployeeSchemaAppA07 Rb20EmployeeRb20employeeServicesApp (A02)A08 Rb20EmployeeViewApp (A02 A07 A98 A99)

C03 Rb21EmployeeDBConfigMap (LC99) Everyting to run the Employee - Bottom-Up sample with the database image store—requires DB2—and with a GUI.

A09 Rb21EmployeeModelAppA10 Rb21EmployeeAppA11 Rb21EmployeeMapApp

A12 Rb21EmployeeSchemaAppA13 Rb21EmployeeRb20employeeServicesAppA14 Rb21EmployeeViewApp (A10 A99)

C04 Rb30EmpDeptDBConfigMap (LC99, LC98). Everything to run the Employee and Department - Top-Down sample with the database image store—requires DB2, GUI, and drag-&-drop support..

A15 Rb30EmpDeptModelAppA16 Rb30EmpDeptAppA18 Rb30EmpDeptMapApp

A19 Rb30EmpDeptSchemaAppA20 Rb30EmpDeptRb30empDeptServicesApp (A16)A21 Rb30EmpDeptViewApp (A16 A95 A96 A97 A99)

C05 Rb31EmpDeptDBConfigMap (LC99, LC98) Everyting to run the Employee and Department - Bootom-Up sample with the database image store—requires DB2—and with a GUI.

A22 Rb31EmpDeptModelAppA23 Rb31EmpDeptAppA24 Rb31EmpDeptMapApp

A25 Rb31EmpDeptSchemaAppA26 Rb31EmpDeptRb31empdeptServicesApp (A23)A27 Rb31EmpDeptViewApp (A23 A95 A99)

(XX##): C##=ConfigMap, A##=Application, LX##=X## must be loaded 1st, RC##=Required ConfigMap

Downloadables, ConfigMaps, Applications 357

Table 87. Application Utility Configuration Maps

ID ConfigMap Name (Prerequisites) Description [Applications ( Prereqs) | Applications (Prereqs) ]

C98 Rb99UtilityViewsConfigMap contains reusable non-visual parts

A96 Rb99UtilityViewsApp A97 Rb99OeUtilityViewApp

C99 Rb99UtilityPartsConfigMap contains reusable visual parts

A99 Rb99UtilityPartsAppA95 Rb99VasXOeApp

A98 Rb99EnhancedBusinessTransactionAppA94 Rb99EnhancedRelationshipApp

Page 384: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 88. Import/Export Rb00ConfigMap with All Application (Part 1 of 3)

A## Application (A## Prerequired Application) - Comment - in Import/Export Rb00ConfigMap

----- Employee Forward/Top-Down...A01 Rb20EmployeeModelAppA02 Rb20EmployeeAppA03 Rb20EmployeeServicesApp (A02) - Local Image Data StoreA04 Rb20EmployeeLISViewApp (A03 A99) - Local Image Data StoreA05 Rb20EmployeeMapAppA06 Rb20EmployeeSchemaAppA07 Rb20EmployeeRb20employeeServicesApp (A02)A08 Rb20EmployeeViewApp (A02 A07 A99 A98) - Transactions

----- Employee Backward/Bottom-Up...A09 Rb21EmployeeModelAppA10 Rb21EmployeeAppA11 Rb21EmployeeMapAppA12 Rb21EmployeeSchemaAppA13 Rb21EmployeeRb20employeeServicesApp (A10)A14 Rb21EmployeeViewApp (A13 A99)

----- Employee and Department Forward/Top-Down...A15 Rb30EmpDeptModelAppA16 Rb30EmpDeptAppA17 Rb30EmpDeptServicesApp (A16) - Local Image Data StoreA18 Rb30EmpDeptMapAppA19 Rb30EmpDeptSchemaAppA20 Rb30EmpDeptRb30empdeptServicesApp (A16)A21 Rb30EmpDeptViewApp (A16 A95 A96 A97 A99) - Drag and Drop Departments and Employees

----- Employee and Department Backward/Bottom-Up...A22 Rb31EmpDeptModelAppA23 Rb31EmpDeptAppA24 Rb31EmpDeptMapAppA25 Rb31EmpDeptSchemaAppA26 Rb31EmpDeptRb31empdeptServicesApp (A23)A27 Rb31EmpDeptViewApp (A23 A99) - Department Management View

358 Using VisualAge Smalltalk ObjectExtender

----- Employee and Department Outsid-In (map model and schema)...A28 Rb30EmpDeptRb31EmpDeptMapApp (A15 A25)A29 Rb30EmpDeptRb31EmpDeptServicesApp (A16)A30 Rb30EmpDeptRb31EmpDeptViewApp (A16)

----- Self-Referencing One-To-Many with Link-Object and Link-Table (1:m-1:1 like bill of material)A31 Rb40CategoryModelApp A32 Rb40CategoryApp - model code and viewsA33 Rb40CategoryMapAppA34 Rb40CategorySchemaAppA35 Rb40CategoryServicesApp (A31)

Page 385: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 89. Import/Export Rb00ConfigMap with All Application (Part 2 of 3)

A## Application (A## Prerequired Application) - Comment - in Import/Export Rb00ConfigMap

----- Many-to-Many Associations/RelationshipsA36 Rb50LibraryModelApp - metamodel and model codeA37 Rb50LibraryMapAppA38 Rb50LibrarySchemaAppA39 Rb50LibraryServicesApp (A36)A40 Rb50LibraryViewApp (A36)

----- InheritanceA41 Rb61LibraryModelApp - metamodel and model codeA42 Rb61LibraryMapAppA43 Rb61LibrarySchemaAppA44 Rb61LibraryServicesApp (A41)A45 Rb62LibraryModelApp - metamodel and model codeA46 Rb62LibraryMapAppA47 Rb62LibrarySchemaAppA48 Rb62LibraryServicesApp (A45)

----- Selective Queries - more than XyzHome allInstances select: [ each: | each parse... ]A49 Rb70LibraryModelApp - metamodel and model codeA50 Rb70LibraryMapAppA51 Rb70LibrarySchemaAppA52 Rb70LibraryServicesAppA53 Rb70LibraryXSelSQLApp (A52) - additional queries supported (SQLs in query pool, new services)

----- Nested TransactionsA54 Rb80LibraryModelApp - metamodel and model codeA55 Rb80LibraryApp (A48) - views and utility partsA56 Rb80LibraryMapAppA57 Rb80LibrarySchemaAppA58 Rb80LibraryServicesApp (A54)

----- Concurrent TransactionsA59 Rb90LibraryModelApp - metamodel and model code, predicate definitionA60 Rb90LibraryMapAppA61 Rb90LibrarySchemaApp

Downloadables, ConfigMaps, Applications 359

A62Rb90LibraryServicesApp (A59) - modified queries (SQL with current timestamp extensions)A63 Rb90LibraryViewApp (A59) - collision detection in image and backend data store

----- GIF Image / BLOB Reusable Part - (gif from string and file, string from gif)A64 Rb10GifImageApp

----- Lite Collection and BLOBA65 Rb11EmployeeModelApp - metamodel and model codeA66 Rb11EmployeeMapAppA67 Rb11EmployeeSchemaAppA68 Rb11EmployeeServicesApp (A65)A69 Rb11EmployeeViewApp (A65) - list view with lite collectin, detail view with BLOB

Page 386: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 90. Import/Export Rb00ConfigMap with All Application (Part 3 of 3)

Table 91. Import/Export Rb01ConfigMap with ObjectExtender Modifications)

A## Application (A## Prerequired Application) - Comment - in Import/Export Rb00ConfigMap

----- Other SamplesA71 Rb1to1App - one-to-one detailed; contains model, schema, map, model code, and services all in oneA72 Rb1toMselfReqApp on-to-many detailed; contains mode, schema, map, model code, and servicesA73 Rb0DB2SampleMetaDataApp - metamodel, map, schema (employee/department forward)A74 Rb0DB2SampleModelApp - model codeA75 Rb0DB2SampleServicesAppA76 Rb0DB2SampleViewApp (A74) - A77 Rb0DB2SampleImportMetaDataApp - metamodel,map,schema (employee/department bottom-up)A78 Rb0DB2SampleImportModelApp - model codeA79 Rb0DB2SampleImportServicesAppA80 Rb0DB2SampleImportViewApp (A78) - tree and assign view (employee/manager--->department)A81 Rb1DB2SampleMetaDataApp - metamodel, map, schema (employee top-down)A82 Rb1DB2SampleModelApp - model codeA83 Rb1DB2SampleServicesAppA84 Rb1DB2SampleViewApp (A82)

----- ObjectExtender HelpersA88 VapDatabasePhysicalRulesXApp - enhanced physical name building supportA89 VapInspectorUtilitiesApp V0.2 ("100% unintrusive" business object inspector)

----- Other HelpersA90 DfksListConnectionsApp - Lists connections of VisualAge Smalltalk parts in text/delimiter format for cut/copy/past into parts documentation.

----- Application HelpersA94 Rb99EnhancedRelationshipApp - inserted root class for non-required relationship support (^nil)A95 Rb99VasXOeApp - #referenceString for UndefinedObjectA96 Rb99UtilityViewsApp - reusable SingleReferenceForm with drag-drop supportA97 Rb99OeUtilityViewApp - form to display basicHash as transaction name for auto ID / easy trackingA98 Rb99EnhancedBusinessTransactionAppA99 Rb99UtilityPartsApp - Comparators, Concatenators, Extractor (by selector for sending visually any message (method selector), Copier,...

360 Using VisualAge Smalltalk ObjectExtender

X## Application - Comment - in Import/Export Rb01ConfigMap LOAD with CAUTION!

X01 VapModelGenerationApp V4.5a mm 0.01 - one-to-one/many nil-able associations/relationshipsX02 VapSchemaBrowserApp V4.5a mm 0.01 - foreign key relationship consistency check softenerX03 VapTransactions V 4.5a mm 0.01. - for #hasChanges supportX04 CollisionManagement V 4.5. - unchanged sub-app of X03X05 VapViewPartsApp V 4.5a mm 0.01. - for #hasChanges supportX99 VapInspectorUtilitiesApp V0.1 ("not 100% unintrusive" business object inspector)

Page 387: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Appendix D. Workspaces and System Transcript Output

See also Appendix C, “Downloadables, ConfigMaps, Applications” on page 355.

D.1 Rb20HDL.wsp - Headless Test Workspace

" Rb20HDLW.wsp "" Rb20 Employee HeaDLess test Workspace "" **************************************************** ""NOTE: setup the ’Detailed Trace’ in the ObjectExtender Tools"

" ########## sample output with loacal image datastore ########### "

"******** stepwise ********"

self halt.Rb20EmployeeHome singleton allInstances "--->"’>>>executing allInstances’

Rb20EmployeeDataStore singleton activate "--->"

Rb20EmployeeHome singleton allInstances "--->"’>>>executing allInstances’

Transaction begin.Rb20EmployeeHome singleton create

empNo: ’A12345’;irstNme: ’Fred’; midInit: ’Q’; lastName: ’Smith’;edLevel: 18.

Transaction current commit. "--->"*** Resuming ->{0}( > 14226)*Committing* {1}( > 14226 > 2083)’>>>executing insert’>>>>committing

© Copyright IBM Corp. 1999 361

Rb20EmployeeHome singleton allInstances "--->"’>>>executing allInstances’

" ******* inspect ******** "

"01" | employee |"02" System vapReset."03" Rb20EmployeeDataStore singleton activate."04" Transaction begin."05" employee := Rb20EmployeeHome singleton allInstances first."06" (DbgInspector on: employee) open; halt; close."07" (DbgInspector on: employee lastName) open; halt; close.

Page 388: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

"08" (DbgInspector on: employee) open; halt; close."09" Transaction current commit "--->"*** Resuming ->{0}( > 19631)’>>>executing allInstances’*Committing* {1}( > 19631 > 19018)>>>>committing

"******** allInstances ********"

"01" | employee |"02" System vapReset."03" Rb20EmployeeDataStore singleton activate."04" Transaction begin."05" (DbgInspector on: Rb20Employee allInstances) open; halt; close."06" employee := Rb20EmployeeHome singleton allInstances first."07" employee firstNme."08" (DbgInspector on: Rb20Employee allInstances) open; halt; close."09" employee firstNme: ’Mike’."10" (DbgInspector on: Rb20Employee allInstances) open; halt; close."11" Transaction current commit."12" employee := nil."13" (DbgInspector on: Rb20Employee allInstances) open; halt; close "--->"*** Resuming ->{0}(Shared)( > 19871)*** Resuming ->{0}( > 20463)’>>>executing allInstances’*Committing* {1}( > 20463 > 19871)>>>>committing

" ########## sample output with DB2 datastore ########### "

"******** stepwise********"

self halt.Rb20EmployeeHome singleton allInstances "--->"*** Resuming ->{0}(Shared)( > 17871)’>>>executing allInstances’

362 Using VisualAge Smalltalk ObjectExtender

>>>executing: SELECT T1.bonus, T1.workDept, T1.firstNme, T1.empNo, T1.comm, T1.hireDate, T1.job, T1.midInit, T1.edLevel, T1.lastName, T1.phoneNo, T1.salary, T1.sex, T1.birthDate FROM USERID.Rb20Employee T1>>>executed without error

Rb20EmployeeDataStore singleton activate "--->"

Rb20EmployeeHome singleton allInstances "--->"*** Resuming ->{0}(Shared)( > 17871)’>>>executing allInstances’>>>executing: SELECT T1.bonus, T1.workDept, T1.firstNme, T1.empNo, T1.comm, T1.hireDate, T1.job, T1.midInit, T1.edLevel, T1.lastName, T1.phoneNo, T1.salary, T1.sex, T1.birthDate FROM USERID.Rb20Employee T1

Page 389: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

>>>executed without error

Transaction begin.Rb20EmployeeHome singleton create

empNo: ’A12345’;irstNme: ’Fred’; midInit: ’Q’; lastName: ’Smith’;edLevel: 18.

Transaction current commit. "--->"*** Resuming ->{0}( > 4753)*Committing* {1}( > 4753 > 17871)’>>>executing insert’>>>executing: INSERT INTO USERID.Rb20Employee ( empNo, bonus, workDept, firstNme, comm, hireDate, job, midInit, edLevel, lastName, phoneNo, salary, sex, birthDate ) VALUES ( ’A12345’, NULL, NULL, ’Fred’, NULL, NULL, NULL, ’Q’, 18, ’Smith’, NULL, NULL, NULL, NULL ) >>>executed without error>>>>commiting

Rb20EmployeeHome singleton allInstances "--->"’>>>executing allInstances’>>>executing: SELECT T1.bonus, T1.workDept, T1.firstNme, T1.empNo, T1.comm, T1.hireDate, T1.job, T1.midInit, T1.edLevel, T1.lastName, T1.phoneNo, T1.salary, T1.sex, T1.birthDate FROM USERID.Rb20Employee T1>>>executed without errorAbtIbmCliRow of type: AbtDatabaseDecimalField(BONUS(11)) Data: nilAbtIbmCliFixedCharField(WORKDEPT(3)) Data: nilAbtOdbcVarCharField(FIRSTNME(12)) Data: ’Fred’AbtIbmCliFixedCharField(EMPNO(6)) Data: ’A12345’AbtDatabaseDecimalField(COMM(11)) Data: nilAbtDatabaseDateField(HIREDATE) Data: nilAbtIbmCliFixedCharField(JOB(8)) Data: nilAbtIbmCliFixedCharField(MIDINIT(1)) Data: $QAbtDatabaseShortIntegerField(EDLEVEL) Data: 18AbtOdbcVarCharField(LASTNAME(15)) Data: ’Smith’AbtIbmCliFixedCharField(PHONENO(4)) Data: nilAbtDatabaseDecimalField(SALARY(11)) Data: nilAbtIbmCliFixedCharField(SEX(1)) Data: nilAbtDatabaseDateField(BIRTHDATE) Data: nil

Workspaces and System Transcript Output 363

" ******* inspect ******** "

"01" | employee |"02" System vapReset."03" Rb20EmployeeDataStore singleton activate."04" Transaction begin."05" employee := Rb20EmployeeHome singleton allInstances first."06" (DbgInspector on: employee) open; halt; close."07" (DbgInspector on: employee lastName) open; halt; close."08" (DbgInspector on: employee) open; halt; close."09" Transaction current commit "--->"

Page 390: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

*** Resuming ->{0}(Shared)( > 22888)*** Resuming ->{0}( > 23512)’>>>executing allInstances’>>>executing: SELECT T1.bonus, T1.workDept, T1.firstNme, T1.empNo, T1.comm, T1.hireDate, T1.job, T1.midInit, T1.edLevel, T1.lastName, T1.phoneNo, T1.salary, T1.sex, T1.birthDate FROM USERID.Rb20Employee T1>>>executed without errorAbtIbmCliRow of type: AbtDatabaseDecimalField(BONUS(11)) Data: nilAbtIbmCliFixedCharField(WORKDEPT(3)) Data: nilAbtOdbcVarCharField(FIRSTNME(12)) Data: ’Fred’AbtIbmCliFixedCharField(EMPNO(6)) Data: ’A12345’AbtDatabaseDecimalField(COMM(11)) Data: nilAbtDatabaseDateField(HIREDATE) Data: nilAbtIbmCliFixedCharField(JOB(8)) Data: nilAbtIbmCliFixedCharField(MIDINIT(1)) Data: $QAbtDatabaseShortIntegerField(EDLEVEL) Data: 18AbtOdbcVarCharField(LASTNAME(15)) Data: ’Smith’AbtIbmCliFixedCharField(PHONENO(4)) Data: nilAbtDatabaseDecimalField(SALARY(11)) Data: nilAbtIbmCliFixedCharField(SEX(1)) Data: nilAbtDatabaseDateField(BIRTHDATE) Data: nil*Committing* {1}( > 23512 > 22888)>>>>commiting

"******** allInstances ********"

"01" | employee |"02" System vapReset."03" Rb20EmployeeDataStore singleton activate."04" Transaction begin."05" (DbgInspector on: Rb20Employee allInstances) open; halt; close."06" employee := Rb20EmployeeHome singleton allInstances first."07" employee firstNme."08" (DbgInspector on: Rb20Employee allInstances) open; halt; close."09" employee firstNme: ’Mike’."10" (DbgInspector on: Rb20Employee allInstances) open; halt; close."11" Transaction current commit.

364 Using VisualAge Smalltalk ObjectExtender

"12" employee := nil."13" (DbgInspector on: Rb20Employee allInstances) open; halt; close "--->"*** Resuming ->{0}(Shared)( > 25115)*** Resuming ->{0}( > 25719)’>>>executing allInstances’>>>executing: SELECT T1.bonus, T1.workDept, T1.firstNme, T1.empNo, T1.comm, T1.hireDate, T1.job, T1.midInit, T1.edLevel, T1.lastName, T1.phoneNo, T1.salary, T1.sex, T1.birthDate FROM USERID.Rb20Employee T1>>>executed without errorAbtIbmCliRow of type:

AbtDatabaseDecimalField(BONUS(11)) Data: nilAbtIbmCliFixedCharField(WORKDEPT(3)) Data: nil

Page 391: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

AbtOdbcVarCharField(FIRSTNME(12)) Data: ’Fred’AbtIbmCliFixedCharField(EMPNO(6)) Data: ’A12345’AbtDatabaseDecimalField(COMM(11)) Data: nilAbtDatabaseDateField(HIREDATE) Data: nilAbtIbmCliFixedCharField(JOB(8)) Data: nilAbtIbmCliFixedCharField(MIDINIT(1)) Data: $QAbtDatabaseShortIntegerField(EDLEVEL) Data: 18AbtOdbcVarCharField(LASTNAME(15)) Data: ’Smith’AbtIbmCliFixedCharField(PHONENO(4)) Data: nilAbtDatabaseDecimalField(SALARY(11)) Data: nilAbtIbmCliFixedCharField(SEX(1)) Data: nilAbtDatabaseDateField(BIRTHDATE) Data: nil

*Committing* {1}( > 25719 > 25115)’>>>executing update’>>>executing: UPDATE USERID.Rb20Employee SET bonus = NULL, workDept = NULL, firstNme = ’Mike’, comm = NULL, hireDate = NULL, job = NULL, midInit = ’Q’, edLevel = 18, lastName = ’Smith’, phoneNo = NULL, salary = NULL, sex = NULL, birthDate = NULL WHERE empNo = ’A12345’>>>executed without error>>>>commiting

D.2 Rb30DBCR.txt - DB Table Creation Report

" Rb30DBCR.txt "" Rb30 Employee DB Creation Report "" ****************************************** "(copied from the System Transcript)>>>>setting auto commit on*** Resuming ->{0}(Shared)( > 26866)*** Resuming ->{0}( > 27615)

>>>executing: DROP TABLE USERID.Rb30Employee>>>executed with error: [SQLSTATE=S0002 - [IBM][CLI Driver][DB2/NT] SQL0204N "USERID.RB30EMPLOYEE" is an undefined name. SQLSTATE=42704 [Native Error=-204]]

>>>executing: DROP TABLE USERID.Rb30Department

Workspaces and System Transcript Output 365

>>>executed with error: [SQLSTATE=S0002 - [IBM][CLI Driver][DB2/NT] SQL0204N "USERID.RB30DEPARTMENT" is an undefined name. SQLSTATE=42704 [Native Error=-204]]

*Committing* {1}( > 27615 > 26866)*** Resuming ->{0}( > 30232)>>>executing: CREATE TABLE USERID.Rb30Department ( deptName VARCHAR(29) NOT NULL, location CHARacter(16), deptNo CHARacter(3) NOT NULL,mgrNo CHARacter(6), admrDept CHARacter(3))>>>executed without error

Page 392: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

>>>executing: CREATE TABLE USERID.Rb30Employee ( firstNme VARCHAR(12) NOT NULL, midInit CHARacter(1) NOT NULL, hireDate DATE, salary DECimal(9,2), edLevel SMALLINT NOT NULL, sex CHARacter(1), comm DECimal(9,2), phoneNo CHARacter(4), job CHARacter(8), bonus DECimal(9,2), birthDate DATE, lastName VARCHAR(15) NOT NULL, empNo CHARacter(6) NOT NULL, workDept CHARacter(3))>>>executed without error*Committing* {1}( > 30232 > 26866)*** Resuming ->{0}( > 10157)>>>executing: ALTER TABLE USERID.Rb30Employee ADD PRIMARY KEY ( empNo)>>>executed without error>>>executing: ALTER TABLE USERID.Rb30Department ADD PRIMARY KEY ( deptNo)>>>executed without error>>>executing: ALTER TABLE USERID.Rb30Employee ADD CONSTRAINT employe_workDepart FOREIGN KEY (workDept) REFERENCES USERID.Rb30Department>>>executed without error>>>executing: ALTER TABLE USERID.Rb30Department ADD CONSTRAINT managedDepar_manag FOREIGN KEY (mgrNo) REFERENCES USERID.Rb30Employee>>>executed without error>>>executing: ALTER TABLE USERID.Rb30Department ADD CONSTRAINT depart_administrat FOREIGN KEY (admrDept) REFERENCES USERID.Rb30Department>>>executed without error*Committing* {1}( > 10157 > 26866)>>>>setting auto commit off

366 Using VisualAge Smalltalk ObjectExtender

D.3 Rb30ObjW.wsp - System Transcript (Output Only)

" Rb30ObjW.wsp "" Rb30 Employee and Department Object setup and navigate Workspace "" ************************************************************************************** ""(in Tools set: Basic Trace, Enable Inspectors)"

............. System Transcript output only

Page 393: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

" ================BEG TRANSCRIPT OUTPUT =============="’’’01 Perform a global reset of ObjectExtender’’’’02 Activate the Rb20EmployeeHome’’s datastore.’’’’03 Add TOP department.’===========================a Rb30Department(nil)- - - - - - - - - -a Rb30Department(nil)’>>>executing insert’>>>executing: INSERT INTO USERID.Rb30Department ( deptNo, deptName, location, Rb30Departme_deptN, Rb30Employee_empNo ) VALUES ( ’TOP’, ’TOP Department’, ’TOP location’, ’TOP’, NULL ) >>>executed without error>>>>commiting’’’04 Check TOP department. NOTE: Resume in the Debugger.’’>>>executing find by key’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.deptNo = ’TOP’>>>executed without error’>>>executing retrieveDepartmentsForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.Rb30Departme_deptN = ’TOP’>>>executed without error’Shows TOP with TOP in departments and as administrativeDepartment, and nil as manager’’* self: a Rb30Department(’’TOP’’)* administrativeDepartment: a Rb30Department(’’TOP’’)* departments: OrderedCollection(’’TOP’’ )* manager: nil’’’’05 Add S1A, S1B, and S2A departments.’’>>>executing find by key’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.deptNo = ’TOP’

Workspaces and System Transcript Output 367

>>>executed without error’>>>executing retrieveDepartmentsForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.Rb30Departme_deptN = ’TOP’>>>executed without error===========================a Rb30Department(nil)a Rb30Department(nil)a Rb30Department(nil)- - - - - - - - - -a Rb30Department(nil)

Page 394: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

a Rb30Department(nil)a Rb30Department(nil)’>>>executing insert’>>>executing: INSERT INTO USERID.Rb30Department ( deptNo, deptName, location, Rb30Departme_deptN, Rb30Employee_empNo ) VALUES ( ’S1A’, ’S1A Department’, ’S1A location’, ’TOP’, NULL ) >>>executed without error’>>>executing insert’>>>executing: INSERT INTO USERID.Rb30Department ( deptNo, deptName, location, Rb30Departme_deptN, Rb30Employee_empNo ) VALUES ( ’S1B’, ’S1B Department’, ’S1B location’, ’TOP’, NULL ) >>>executed without error’>>>executing insert’>>>executing: INSERT INTO USERID.Rb30Department ( deptNo, deptName, location, Rb30Departme_deptN, Rb30Employee_empNo ) VALUES ( ’S2A’, ’S2A Department’, ’S2A location’, ’S1A’, NULL ) >>>executed without error>>>>commiting’’’06 Add employees & managers except one to departments.’’>>>executing find by key’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.deptNo = ’TOP’>>>executed without error’>>>executing retrieveEmployeesForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.firstNme, T1.midInit, T1.hireDate, T1.salary, T1.edLevel, T1.sex, T1.comm, T1.phoneNo, T1.job, T1.bonus, T1.birthDate, T1.lastName, T1.empNo, T1.Rb30Departme_deptN FROM USERID.Rb30Employee T1 WHERE T1.Rb30Departme_deptN = ’TOP’>>>executed without error’>>>executing retrieveDepartmentsForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.Rb30Departme_deptN = ’TOP’>>>executed without error’>>>executing retrieveEmployeesForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.firstNme, T1.midInit, T1.hireDate, T1.salary, T1.edLevel, T1.sex, T1.comm, T1.phoneNo, T1.job, T1.bonus, T1.birthDate, T1.lastName, T1.empNo, T1.Rb30Departme_deptN FROM USERID.Rb30Employee T1 WHERE T1.Rb30Departme_deptN =

368 Using VisualAge Smalltalk ObjectExtender

’S1B’>>>executed without error’>>>executing retrieveEmployeesForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.firstNme, T1.midInit, T1.hireDate, T1.salary, T1.edLevel, T1.sex, T1.comm, T1.phoneNo, T1.job, T1.bonus, T1.birthDate, T1.lastName, T1.empNo, T1.Rb30Departme_deptN FROM USERID.Rb30Employee T1 WHERE T1.Rb30Departme_deptN = ’S1A’>>>executed without error===========================a Rb30Department(’TOP’)a Rb30Employee(nil)a Rb30Employee(nil)

Page 395: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

a Rb30Department(’S1B’)a Rb30Employee(nil)a Rb30Employee(nil)a Rb30Employee(nil)a Rb30Employee(nil)- - - - - - - - - -a Rb30Employee(nil)a Rb30Employee(nil)a Rb30Department(’S1B’)a Rb30Employee(nil)a Rb30Employee(nil)a Rb30Employee(nil)a Rb30Department(’TOP’)a Rb30Employee(nil)’>>>executing insert’>>>executing: INSERT INTO USERID.Rb30Employee ( empNo, firstNme, midInit, hireDate, salary, edLevel, sex, comm, phoneNo, job, bonus, birthDate, lastName, Rb30Departme_deptN ) VALUES ( ’EMP1A2’, ’EMP1A2first’, ’E’, NULL, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, ’EMP1A2last’, ’S1A’ ) >>>executed without error’>>>executing insert’>>>executing: INSERT INTO USERID.Rb30Employee ( empNo, firstNme, midInit, hireDate, salary, edLevel, sex, comm, phoneNo, job, bonus, birthDate, lastName, Rb30Departme_deptN ) VALUES ( ’EMP1B0’, ’EMP1B0first’, ’E’, NULL, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, ’EMP1B0last’, ’S1B’ ) >>>executed without error’>>>executing update’>>>executing: UPDATE USERID.Rb30Department SET deptName = ’S1B Department’, location = ’S1B location ’, Rb30Departme_deptN = ’TOP’, Rb30Employee_empNo = ’EMP1B0’ WHERE deptNo = ’S1B’>>>executed without error’>>>executing insert’>>>executing: INSERT INTO USERID.Rb30Employee ( empNo, firstNme, midInit, hireDate, salary, edLevel, sex, comm, phoneNo, job, bonus, birthDate, lastName, Rb30Departme_deptN ) VALUES ( ’EMP1B1’, ’EMP1B1first’, ’E’, NULL, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, ’EMP1B1last’, ’S1B’ ) >>>executed without error’>>>executing insert’>>>executing: INSERT INTO USERID.Rb30Employee ( empNo, firstNme, midInit, hireDate, salary,

Workspaces and System Transcript Output 369

edLevel, sex, comm, phoneNo, job, bonus, birthDate, lastName, Rb30Departme_deptN ) VALUES ( ’EMP1A1’, ’EMP1A1first’, ’E’, NULL, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, ’EMP1A1last’, ’S1A’ ) >>>executed without error’>>>executing insert’>>>executing: INSERT INTO USERID.Rb30Employee ( empNo, firstNme, midInit, hireDate, salary, edLevel, sex, comm, phoneNo, job, bonus, birthDate, lastName, Rb30Departme_deptN ) VALUES ( ’EMPTP0’, ’EMPTP0first’, ’T’, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, ’EMPTP0last’, ’TOP’ ) >>>executed without error’>>>executing update’>>>executing: UPDATE USERID.Rb30Department SET deptName = ’TOP Department’, location =

Page 396: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

’TOP location ’, Rb30Departme_deptN = ’TOP’, Rb30Employee_empNo = ’EMPTP0’ WHERE deptNo = ’TOP’>>>executed without error’>>>executing insert’>>>executing: INSERT INTO USERID.Rb30Employee ( empNo, firstNme, midInit, hireDate, salary, edLevel, sex, comm, phoneNo, job, bonus, birthDate, lastName, Rb30Departme_deptN ) VALUES ( ’EMPXXX’, ’EMPXXXfirst’, ’E’, NULL, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, ’EMPXXXlast’, NULL ) >>>executed without error>>>>commiting’’’07 Verify Object Setup - List Department Hierarchy with Contents...’’>>>executing find by key’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.deptNo = ’TOP’>>>executed without error’>>>executing retrieveDepartmentsForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.Rb30Departme_deptN = ’TOP’>>>executed without error’>>>executing find by key’>>>executing: SELECT T1.firstNme, T1.midInit, T1.hireDate, T1.salary, T1.edLevel, T1.sex, T1.comm, T1.phoneNo, T1.job, T1.bonus, T1.birthDate, T1.lastName, T1.empNo, T1.Rb30Departme_deptN FROM USERID.Rb30Employee T1 WHERE T1.empNo = ’EMPTP0’>>>executed without error’>>>executing retrieveEmployeesForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.firstNme, T1.midInit, T1.hireDate, T1.salary, T1.edLevel, T1.sex, T1.comm, T1.phoneNo, T1.job, T1.bonus, T1.birthDate, T1.lastName, T1.empNo, T1.Rb30Departme_deptN FROM USERID.Rb30Employee T1 WHERE T1.Rb30Departme_deptN = ’TOP’>>>executed without error’>>>executing retrieveDepartmentsForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.Rb30Departme_deptN = ’S1B’>>>executed without error’>>>executing find by key’>>>executing: SELECT T1.firstNme, T1.midInit, T1.hireDate, T1.salary, T1.edLevel, T1.sex,

370 Using VisualAge Smalltalk ObjectExtender

T1.comm, T1.phoneNo, T1.job, T1.bonus, T1.birthDate, T1.lastName, T1.empNo, T1.Rb30Departme_deptN FROM USERID.Rb30Employee T1 WHERE T1.empNo = ’EMP1B0’>>>executed without error’>>>executing retrieveEmployeesForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.firstNme, T1.midInit, T1.hireDate, T1.salary, T1.edLevel, T1.sex, T1.comm, T1.phoneNo, T1.job, T1.bonus, T1.birthDate, T1.lastName, T1.empNo, T1.Rb30Departme_deptN FROM USERID.Rb30Employee T1 WHERE T1.Rb30Departme_deptN = ’S1B’>>>executed without error’>>>executing retrieveDepartmentsForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE

Page 397: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

T1.Rb30Departme_deptN = ’S1A’>>>executed without error’>>>executing retrieveEmployeesForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.firstNme, T1.midInit, T1.hireDate, T1.salary, T1.edLevel, T1.sex, T1.comm, T1.phoneNo, T1.job, T1.bonus, T1.birthDate, T1.lastName, T1.empNo, T1.Rb30Departme_deptN FROM USERID.Rb30Employee T1 WHERE T1.Rb30Departme_deptN = ’S1A’>>>executed without error’>>>executing retrieveDepartmentsForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.Rb30Departme_deptN = ’S2A’>>>executed without error’>>>executing retrieveEmployeesForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.firstNme, T1.midInit, T1.hireDate, T1.salary, T1.edLevel, T1.sex, T1.comm, T1.phoneNo, T1.job, T1.bonus, T1.birthDate, T1.lastName, T1.empNo, T1.Rb30Departme_deptN FROM USERID.Rb30Employee T1 WHERE T1.Rb30Departme_deptN = ’S2A’>>>executed without error’|---a Rb30Department(’’TOP’’)| |---admrDept: a Rb30Department(’’TOP’’)| |---departments: OrderedCollection(’’TOP’’ ’’S1A’’ ’’S1B’’ )| |---manager: EMPTP0| |---employees: OrderedCollection(’’EMPTP0’’ )| |---a Rb30Department(’’S1B’’)| | |---admrDept: a Rb30Department(’’TOP’’)| | |---departments: OrderedCollection()| | |---manager: EMP1B0| | |---employees: OrderedCollection(’’EMP1B0’’ ’’EMP1B1’’ )| |---a Rb30Department(’’S1A’’)| | |---admrDept: a Rb30Department(’’TOP’’)| | |---departments: OrderedCollection(’’S2A’’ )| | |---manager: none| | |---employees: OrderedCollection(’’EMP1A2’’ ’’EMP1A1’’ )| | |---a Rb30Department(’’S2A’’)| | | |---admrDept: a Rb30Department(’’S1A’’)| | | |---departments: OrderedCollection()| | | |---manager: none

Workspaces and System Transcript Output 371

| | | |---employees: OrderedCollection()’’’’N0 Setup Navigate (ObjectExtender general reset, dataStore activate.’’’’N1a Find the departments of the S1A department.’’>>>executing find by key’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.deptNo = ’S1A’>>>executed without error’>>>executing retrieveDepartmentsForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE

Page 398: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

T1.Rb30Departme_deptN = ’S1A’>>>executed without errorOrderedCollection(’S2A’ )’’’N1b Find the departments of the S1B department.’’>>>executing find by key’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.deptNo = ’S1B’>>>executed without error’>>>executing retrieveDepartmentsForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.Rb30Departme_deptN = ’S1B’>>>executed without errorOrderedCollection()’’’N1c Find the departments of the TOP department.’’>>>executing find by key’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.deptNo = ’TOP’>>>executed without error’>>>executing retrieveDepartmentsForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.Rb30Departme_deptN = ’TOP’>>>executed without errorOrderedCollection(’TOP’ ’S1A’ ’S1B’ )’’’N2a Find the administr. dept. of the S1A department.’’>>>executing find by key’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.deptNo = ’S1A’>>>executed without error’>>>executing find by key’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.deptNo = ’TOP’>>>executed without error’>>>executing retrieveDepartmentsForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN,

372 Using VisualAge Smalltalk ObjectExtender

T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.Rb30Departme_deptN = ’TOP’>>>executed without error’TOP’’’’N2b Find the administr. dept. of the TOP department.’’>>>executing find by key’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.deptNo = ’TOP’>>>executed without error’>>>executing retrieveDepartmentsForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN,

Page 399: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.Rb30Departme_deptN = ’TOP’>>>executed without error’TOP’’’’N3a Find the employees of the S1B department.’’>>>executing find by key’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.deptNo = ’S1B’>>>executed without error’>>>executing retrieveEmployeesForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.firstNme, T1.midInit, T1.hireDate, T1.salary, T1.edLevel, T1.sex, T1.comm, T1.phoneNo, T1.job, T1.bonus, T1.birthDate, T1.lastName, T1.empNo, T1.Rb30Departme_deptN FROM USERID.Rb30Employee T1 WHERE T1.Rb30Departme_deptN = ’S1B’>>>executed without errorOrderedCollection(’EMP1B0’ ’EMP1B1’ )’’’N3b Find the employees of the S2A department.’’>>>executing find by key’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.deptNo = ’S2A’>>>executed without error’>>>executing retrieveEmployeesForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.firstNme, T1.midInit, T1.hireDate, T1.salary, T1.edLevel, T1.sex, T1.comm, T1.phoneNo, T1.job, T1.bonus, T1.birthDate, T1.lastName, T1.empNo, T1.Rb30Departme_deptN FROM USERID.Rb30Employee T1 WHERE T1.Rb30Departme_deptN = ’S2A’>>>executed without errorOrderedCollection()’’’N4a Find the work department of empl. EMP1B0 (if any).’’>>>executing find by key’>>>executing: SELECT T1.firstNme, T1.midInit, T1.hireDate, T1.salary, T1.edLevel, T1.sex, T1.comm, T1.phoneNo, T1.job, T1.bonus, T1.birthDate, T1.lastName, T1.empNo, T1.Rb30Departme_deptN FROM USERID.Rb30Employee T1 WHERE T1.empNo = ’EMP1B0’>>>executed without error’>>>executing find by key’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN,

Workspaces and System Transcript Output 373

T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.deptNo = ’S1B’>>>executed without error’>>>executing retrieveEmployeesForRb30Department: aRb30DepartmentKey ’>>>executing: SELECT T1.firstNme, T1.midInit, T1.hireDate, T1.salary, T1.edLevel, T1.sex, T1.comm, T1.phoneNo, T1.job, T1.bonus, T1.birthDate, T1.lastName, T1.empNo, T1.Rb30Departme_deptN FROM USERID.Rb30Employee T1 WHERE T1.Rb30Departme_deptN = ’S1B’>>>executed without errora Rb30Department(’S1B’)’’’N4b Find the work department of empl. EMPXXX (if any).’’>>>executing find by key’

Page 400: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

>>>executing: SELECT T1.firstNme, T1.midInit, T1.hireDate, T1.salary, T1.edLevel, T1.sex, T1.comm, T1.phoneNo, T1.job, T1.bonus, T1.birthDate, T1.lastName, T1.empNo, T1.Rb30Departme_deptN FROM USERID.Rb30Employee T1 WHERE T1.empNo = ’EMPXXX’>>>executed without errornil’’’N5a Find the manager of the S1B department (if any).’’>>>executing find by key’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.deptNo = ’S1B’>>>executed without errora Rb30Employee(’EMP1B0’)’’’N5b Find the manager of the S1A department (if any).’’>>>executing find by key’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.deptNo = ’S1A’>>>executed without errornil’’’N6a Find the managed department of EMP1B0 (if any).’’>>>executing find by key’>>>executing: SELECT T1.firstNme, T1.midInit, T1.hireDate, T1.salary, T1.edLevel, T1.sex, T1.comm, T1.phoneNo, T1.job, T1.bonus, T1.birthDate, T1.lastName, T1.empNo, T1.Rb30Departme_deptN FROM USERID.Rb30Employee T1 WHERE T1.empNo = ’EMP1B0’>>>executed without error’>>>executing retrieveManagedDepartmentForRb30Employee: aRb30EmployeeKey ’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.Rb30Employee_empNo = ’EMP1B0’>>>executed without errora Rb30Department(’S1B’)’’’N6b Find the managed department of EMP1B1 (if any).’’>>>executing find by key’>>>executing: SELECT T1.firstNme, T1.midInit, T1.hireDate, T1.salary, T1.edLevel, T1.sex, T1.comm, T1.phoneNo, T1.job, T1.bonus, T1.birthDate, T1.lastName, T1.empNo, T1.Rb30Departme_deptN FROM USERID.Rb30Employee T1 WHERE T1.empNo = ’EMP1B1’>>>executed without error

374 Using VisualAge Smalltalk ObjectExtender

’>>>executing retrieveManagedDepartmentForRb30Employee: aRb30EmployeeKey ’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.Rb30Employee_empNo = ’EMP1B1’>>>executed without error/////////////////// DEBUGS - ZAP EDITING THE RECEIVER CLASS ////////////////////////////overide implementation with copy of it in the receiver class, but with change below: Rb1to1EmployeeToManagedDepartmentRelationship>>#objectForForeignKey: anFkey....ifTrue: [^nil "self error: VapNoObjectFound"] "No object found" Info: 42 Rb30EmployeeToManagedDepartmentRelationship overriding #objectForForeignKey: from

Page 401: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Relationship.////////// DROP IN FRAME PRECEDING THE ERROR AND RESUEM //////////////////////’>>>executing retrieveManagedDepartmentForRb30Employee: aRb30EmployeeKey ’>>>executing: SELECT T1.deptName, T1.location, T1.deptNo, T1.Rb30Departme_deptN, T1.Rb30Employee_empNo FROM USERID.Rb30Department T1 WHERE T1.Rb30Employee_empNo = ’EMP1B1’>>>executed without errornil’’

Workspaces and System Transcript Output 375

Page 402: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

376 Using VisualAge Smalltalk ObjectExtender

Page 403: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Appendix E. Library Management System

This appendix recalls the details of the Library Management System as modeled in the IBM Redbook, Using VisualAge UML Designer, SG24-4997. VisualAge (Smalltalk) UML Designer is IBM’s object-oriented modeling tool to roundtrip engineer Smalltalk and forward engineer Java code. The details about the Library Management System are:

• Requirements - (Table 92 on page 378) • Concepts - (Table 93 on page 378 and Table 94 on page 379) • Actors - (Table 95 on page 380) • List of use cases - (Table 210 on page 381) • Use case descriptions with hyper link marks - (Table 96 through Table 98) • System overview - (Figure 211 on page 385) • Use case diagrams - (Figure 212 on page 385 through Figure 214) • Class diagram - (Table 215 on page 387)

© Copyright IBM Corp. 1999 377

Page 404: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 92. Library Management System: Requirements

Table 93. Library Management System: Concepts 1

Requirement Name Details

Book Information Keeping

Keep information about the books of a library. Books have to be kept as titles and physical copies - the books themselves. Each must have his own unique identification.

Customer Information Keeping

Keep information about the customers of a library. Each customer must have a unique identification.

Book Loan Information Keeping

Keep book loan information. Distinguish among available, borrowed, overdue, reserved, and lost.

Books on Loan Searching

Support the search for books on loan (borrowed and/or overdue) of one title or of a customer.

Customer Searching Support the search for customers.

Title Searching Support the search for titles by words in the title and abstract, by author, and/or by category.

Title Reservation Support the reservation of a title for a customer for a limited time up to a specific date, if all physical copies are loaned.

End-of-Day Processing

Perform end-of-day processing, which includes updating reservations and loans.

Concept Name Details (so far)

Available A book available for any customer has the status available.

Borrowed A book on loan - but not overdue - is in the status borrowed.

Overdue A book longer on loan than agreed is in the status overdue.

Lost A book on loan that the customer is unable to find and return.

378 Using VisualAge Smalltalk ObjectExtender

Reserved A book available for only that customer for whom the reservation was made.

Returned A book just returned by a customer - becomes either available or reserved.

Book Loan ... the current and legal user (reader) is not the legal owner...Book borrowed from the Library for temporary use - up to the agreed return date.

Identification Unique information to uniquely identify something. For example: Social Security Number (SNN), employee number or any serial number. Abbreviations used: ID or id.

Category Contents qualification. For example: Science Fiction.

Page 405: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 94. Library Management System: Concepts 2

Concept Name Details (so far)

Abstract Short text about the book’s contents.

Author Name of the person(s) who wrote the book.

Bar Code Sequence of bars coding a number. Easy, fast, and reliable for machines to read.

Book Label A label with the book’s identification in standard type face and as barcode, primary category (of the title), author, and some other pertinent information to stick on the book spine and on its first page.

Customer Search Criteria

A set of selection values used to search a specific customer in the customer file. It is obvious, that latest at implementation time it looks like an object.

Default Reservation Period

Number of days a Title can be reserved. Every Title can have its own default. If not set, the systemwide default is taken.

Expiration Date of a Reservation: the date up to which a title reservation is kept.

Expired Book Loan

Book not returned before or at the agreed return date. An expired loan is overdue.

Expired Reservation

Reserved Book of a Title not picked up before or at the reservation expiration date. The reservation is removed.

ISBN International Standardized Book Number, identification defined by the publishers

Library Membership

The state of being a member of the Library organization - the borrowing part.

Library Membership Card

A card in credit card size identifying a person or customer of the Library Membership. The customer id, firstname, middle initial, lastname, member Since date, and photo are printed on it. Id and member Since date are also printed as bar code.

Match String A search criteria item that can have wildcards for fuzzy search. The number sign (#) represents any single character, whereas an asterisk (*) represents any character string.

Library Management System 379

Matching Title A title which matches the match strings of the title search criteria.

Publisher Name of person(s) or organization(s) publishing the book.

System The group of the acting objects building a reasonable, complete unit. If a system is called doing this or that, in fact one of its objects is doing this or that.

Title Search Criteria

A set of selection values used to search a specific title in the title catalog. It is obvious, that latest at implementation time it looks like an object.

ZIP 5-digit postal delivery area. - ZIP Code - A trademark for a system to expedite the delivery of mail by assigning a 5-digit number to each postal delivery area in the U.S.

Page 406: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 95. Library Management System: Actors

Actor Name Description

Librarian Employee of a Book Library. Main user of the Book Loan System, having extended access to information and processes. Serving and helping the Library Customers in Book Loans and Returns, Title Searches and Reservations.

Maintains Books - Add, Update, Remove -, sticks the printed Labels on the Book, is aware of the Book’s Title and the Title’s Categories.

Maintains Customers - Add, Update, Remove -, hands out the printed Library Membership Card.

Manages Book Loans - Check Out Books, Book Returns.

Searches Books on Loan with Title or Customer information, Searches Customers and Searches Titles.

Creates Reservation with Title and Customer information, can overwrite the Reservation Expiration Date.

Enters and Looks at Book and Title Details.

Enters and Looks at Customer Details.

Maintains the Category List.

Enters the condition of returned Books, if changed, and sets the Status of not returned Books to lost.

Customer Customer borrowing Books from the Library. Casual user of the Library System, having restricted access to information and processes.

Searches Books on Loan with his or her ID and Title information

Searches Titles.

Reserves Titles with his or her ID and Title information.

380 Using VisualAge Smalltalk ObjectExtender

-

System Timer Device or Operator triggering predefined, scheduled tasks.

Starts the daily Process End-Of-Day task.

-

Page 407: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Library Management System 381

Figure 210. Library Management System: Use Case List and Sample Use Case

Note: The "human being" represents an actor, the circle a thing (a potential object class), the bulb a concept, and the oval a use case.

Page 408: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 96. Library Management System: Main Use Cases with Hyper Link Marks

Name Details with Hyper Links: <Actor>, (Thing), |Concept|, {extends} & [used] use case

Maintain Books

The <Librarian> does maintain (Book) information in the (Book File) - {Add Book}, {Update Book}, and {Remove Book} information -, and print |Book Label|s. When adding a book, the Librarian has to be aware of the Book’s (Title) and |Category|s.

Maintain Customers

The <Librarian> does maintain (Customer) information in the (Customer File) - {Add Customer}, {Update Customer}, and {Remove Customer} information -, and print |Library Membership Card|.

Manage Book Loans

The <Librarian> does manage |Book Loan|s through {Check Out Books} with a default Return Date and a (Customer) individual maximum Number Of Items On Loan check, and through {Return Books} - affecting (Book) (Status) in the (Status File) - according to |Available|, |Borrowed|, |Overdue|, |Lost|, or |Reserved|.

Search Books On Loan

The <Librarian> does search (Books) of a (Title) or a (Customer) has on loan, whereas the <Customer> does search Books of a Title or his or her Books on loan.

- The Librarian optionally enters a Customer |Identification| whereas the Customer must enter his or her Identification, in order to start the search.- {Search Customers} and {Search Titles} are available.

Search Customers

The <Librarian> and <Customer> search (Customer)s in (Customer File) and can {Look At Customer Details}. A customer has restricted search only.

- The |Customer Search Criteria| are: id |Identification|, firstname, middle initials, lastname, street, city, and Customer mandatory: |ZIP|, phone number, and |SSN|.

Search Titles The <Librarian> and <Customer> search (Title)s in the (Title Catalog). The |Title Search Criteria| are: words in the |Title| and |Abstract|, name of the |Author|, and by |Category|s from the (Category List).

- The Librarian and Customer enter the Title Search Criteria as |Match String|s, start the search, get a list with |Matching Title|s presented, and can {Look At Title Details}.

Reserve Title The <Librarian> and <Customer> create a (Reservation) of a (Book) (Title) for a (Customer) in the (Reservation File) in the event that all physical copies are on loan.

382 Using VisualAge Smalltalk ObjectExtender

- The Librarian and Customer enter the Customer and Title |Identification|. The Librarian can set the reservation |Expiration Date|, where as the Customer has to use the default.- (Search Customers) and (Search Titles) are available.

Process End-Of-Day

The <System Timer> does start the Process End-Of-Day task of the Files: delete |Expired Reservation|s (Title)/(Book) (Reservation)s in the (Title Catalog) (Reservation File) and update |Expired Book Loan|s with (Book) (Status) changes |Reserved|/|Available| and |Borrowed|/|Overdue| in the (Book File) (Status File).

Page 409: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 97. Library Management System: Extending and Used Use Cases 1 with Link Marks

Name Details with Hyper Links: <Actor>, (Thing), |Concept|, {extends} & [used] use case

Add Book When the Library gets new books delivered, the <Librarian> does {Enter Book Details} and add (Book) to the (Book File), and [Print Book Labels]. The System - Book File - does assign Book ID |Identification| and entry Date.

Update Book When a Book information needs corrections, the <Librarian> does enter the Book ID |Identification| directly or via {Search Books}, [Enter Book Details], and update the (Book) in the (Book File), and when necessary, re{Print Book Labels}.

Remove Book When a Book is no longer up to date or is damaged, the <Librarian> does enter the Book ID |Identification| directly or via {Search Books}, [Look At Book Details], and remove the (Book) from the (Book File).

Search Books The <Librarian> enters the (Title) |Identification| directly or via {Search Titles} to search (Book)s in the (Book File).

Enter Book Details

The <Librarian> assigns the (Title) directly or via {Search Titles} to the (Book), then enters its (Status), and condition. The Librarian might {Maintain Titles} first.

Look at Book Details

The <Librarian> and <Customer> look at the Book Information: (Title), (Status) with (Customer) reference, if any and Librarian only, condition, and entry Date.

Print Book Labels

The <Librarian> prints the |Book Label|s to stick on the spine and the first page: (Book) ID, (Title) ID, title, |Author|, and primary |Category| - IDs also as |Bar Code|.

Maintain Titles The <Librarian> does maintain (Title) information in the (Title File) - {Add Title}, {Update Title}, and {Remove Title} information. When adding a Title, the Librarian has to be aware of its primary and secondary |Category|s.

Add Title If the Title of a new delivered book is not yet in the system, the <Librarian> does {Enter Title Details} and add the (Title) to the Title File, called (Title Catalog). The System - Title Catalog - does assign Title ID - |Identification| - and entry Date.

Update Title When a Title information needs corrections, the <Librarian> does enter the Title ID |Identification| directly or via {Search Titles}, [Enter Title Details], and update the (Title) in the Title File, called (Title Catalog). The (Book) labels might be reprinted.

Library Management System 383

Remove Title If there are no Books of that Title in the Library anymore, the title might be removed: the <Librarian> does enter the Title ID |Identification| directly or via {Search Titles}, [Look At Title Details] and remove the (Title) from the Title File, called (Title Catalog).

Enter Title Details

The <Librarian> enters the |Title| details - title, |Author|, |ISBN|, |Abstract|, number Of Pages, |Publisher|, publication Date, assigns one primary and none to many secondary |Category|s from the (Category List), and scans or shoots an image of the cover. The Librarian might {Maintain Category List} first.

Look at Title Details

The <Librarian> or <Customer> look at the (Title) details, on request including cover image, and number of (Book)s |Available|, |Reserved| and total in Library.

Page 410: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 98. Library Management System: Extending and Used Use Cases 2 with Link Marks

Name Details with Hyper Links: <Actor>, (Thing), |Concept|, {extends} & [used] use case

Add Customer When a person becomes a Customer of the Library, the <Librarian> does [Enter Customer Details], add the (Customer) to the (Customer File), and [Print Library Membership Card]. The System - Customer File - does assign Customer ID - |Identification| - and the member Since date.

Update Customer

When a Customer information needs corrections, the <Librarian> does enter the Customer ID |Identification| directly - from the |Library Membership Card| - or via {Search Customer}, [Enter Customer Details], update the (Customer) in the (Customer File), and when necessary, re{Print Library Membership Card}.

Remove Customer

When a Customer cancels his or her |Library Membership|, the <Librarian> does enter the Customer ID |Identification| directly - from the |Library Membership Card| - or via {Search Customers}, [Look At Customer Details], and - when no |Books| on loan - remove the (Customer) from the (Customer File).

Enter Customer Details

The <Librarian> enters the (Customer) details - firstname, middle initial, lastname, street, city, state, |ZIP|, phone Number, |SSN| -, optionally changes the system defaulted maximum Number Of Items On Loan, and shoots a photo. ID |Identification| and member Since date are set by the system at add time.

Look at Customer Details

The <Librarian> and <Customer> look at the (Customer) details: id for |Identification|, firstname, middle initial, lastname, street, city, state, |ZIP|, phone Number, member Since date, maximum Number Of Items On Loan, |SSN|, and photo. A customer can only see own details.

Print Library Membership Card

The <Librarian> prints the |Library Membership Card| for the (Customer) with: id for |Identification|, firstname, middle initial, lastname, memberSince date, and photo. ID and memberSince date are printed also as |Bar Code|.

Maintain Category List

The <Librarian> maintains |Category|s (Category)s - with ID |Identification|, word or phrase, and short text - in the (Category List) stored in the (Category File).

Return Books The Customer returns Books on loan at the Loan Returns window to the Librarian. The <Librarian> enters each (Book) ID |Identification| and condition - if condition changed. A return affects the Book (Status) accordingly... sometimes to |Lost| - {Search Books},

384 Using VisualAge Smalltalk ObjectExtender

{Search Books On Loan}, and {Search Customers} are available. The system displays Customer details, books on loan with return Dates, and Books lost, as soon as it knows the |Customer| ID - by entry or via Books in return.

Check Out Books

The Customer checks out Books at the New Loans window with the Library Membership Card. The <Librarian> identifies the (Customer) by the |Library Membership Card| or {Search Customers} and {Look At Customer Details}, enters the Customer ID |Identification| - from the Library Membership Card -, and each (Book) ID - from the Label. A loan affects the Book (Status) accordingly. The system displays customer details, books on loan with returnDate, and lost books, and restricts the loan to the maximum Number Of Items On Loan.

Page 411: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 211. Library Management System: Overview Diagram

Library Management System 385

Figure 212. Library Management System: Book Management Use Case Diagram

Page 412: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 213. Library Management System: Customer Management Use Case Diagram

386 Using VisualAge Smalltalk ObjectExtender

Figure 214. Library Management System: Book Loan Management Use Case Diagram

Page 413: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 215. Library Management System: Class Diagram

Library Management System 387

Note: The status attribute—with the values available, borrowed, overdue, lost, and reserved—was removed from the Book (book copy) class and converted into the Status class hierarchy (Figure 215). The Status class hierarchy implements the state design pattern to make the loan part of the system a reusable framework.

Page 414: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

388 Using VisualAge Smalltalk ObjectExtender

Page 415: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Appendix F. Some Survival Stuff

In this appendix we present some survival stuff to make life easy.

F.1 VapModelBrowserControl>>#deleteAssociation

Figure 216 shows the zap that enables you to delete unfinished associations in the model. The unfinished associations have nil in the model, are not editable, are not deleteable, prevent you from adding new ones (except you delete the whole model), and sometimes do not show up in the associations list of the Model Browser. (Close the Model Browser and reopen it to force them to show up).

Figure 216. Zap to Enable Deletion of Unfinished Class Associations

F.2 VapSchemaColumnEditorModel>> #areForeignKeysValid

VapModelBrowserControl>>#deleteAssociation

>

>>>>>>

deleteAssociation| association model |association := self selectedAssociation.(model := association model) == nil ifTrue: [

model := self selectedModel.(CwMessagePrompter confirm: ’Delete Association ’

, association printString , ’ in Model ’, model printString , ’?’ ) ifFalse: [^self] ].

model removeElement: association.

self markModelDirty

© Copyright IBM Corp. 1999 389

When you try to change the type of columns that are part of a foreign key relationship, you get an error such as that shown in Figure 217. ObjectExtender’s consistency check stops you from changing key column types directly, if they are part of a relationship.

You either delete all foreign key relationships, change the key column types, and reenter the foreign key relationships, or you make a minor zap as suggested in Figure 218. If you choose to zap, the foreign key definition consistency becomes your responsibility, and you have to take care of broken property mappings in the map caused by key definition inconsistencies. Another approach is to define the model without the associations, generate

Page 416: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

the schema, change the primary key column types, and then define the associations in the model and complement the schema by generating just the foreign key associations.

Figure 217. Error When Trying to Change a Key Column Type

VapSchemaColumnEditorModel>>#areForeignKeysValid

>

>

areForeignKeysValid

"Answer a boolean if the any foreign keys that the column participates in are validFirst create a column that has the values we intend to commit ( the preview column )The bomb around each foreign key and if it has a column that maps to us check whether we are isomorphic. If not error and return false --- if not confirmed to change anyway."

| previewColumn |

previewColumn := myColumn copy.self updateColumn: previewColumn.

myColumn table foreignKeys do: [ :key || oppositeColumn | oppositeColumn := key columnMappedWith: myColumn.oppositeColumn notNil ifTrue: [ ( oppositeColumn isomorphic: previewColumn ) ifFalse: [ ^(CwMessagePrompter warn: "System errorMessage:" ( VapSchemaBrowserString122

"The foreign key component %1 does not match the type of its primary key counter-part"

390 Using VisualAge Smalltalk ObjectExtender

Figure 218. Zap to Enable Direct Foreign Key Relationship Column Type Change

With the zap shown in Figure 218, the first mismatch triggers the warning shown in Figure 219. After you accept the mismatches, your Foreign Key Relationships list shows inconsistent items, indicated by two less than (<<) characters in front of the relation name (Figure 220 on page 391). You may have to refresh the foreign key relationships list by clicking on

>>

bindWith: key name, ’ ’, oppositeColumn printString) , ’, and - may be - others as well.’ ) == true ."^false" ] ] ].

^true

Page 417: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

the model. After you change all affected key column types to the new definitions, the inconsistencies disappear. Again, you may have to refresh the foreign key relationships list by clicking on the model.

Figure 219. Key Column Type Definition Inconsistency Warning

Figure 220 shows foreign key relationships with inconsistent key type definitions.

Figure 220. Inconsistent Foreign Key Relationships

F.3 Required Self-Associations

The Resource>>#updateIndex:in:startingAt: runs for the TOP department into a Stack Overflow walkback, because the TOP department contains also itself in the departments collection, and ObjectExtender iterates over the departments collection, to reach all objects and update the sort indices for each collection element. The runtime system code zap of the line with the

Some Survival Stuff 391

nil-check of the targetB(usiness)o(bject) aTargetBo notNil in Figure 221 ensures that required self-references are processed only once. The check must be complemented with the self-referencing or recursion-break check. Finally the line reads (new part in bold):

aTargetBo notNil & (aTargetBo ~~ version businessObject)

Page 418: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 221. Zap for Required Self Referencing Associations (Stack OVerflow)

For a sample with test scripts focusing on the one-to-many and self-referencing-required association, see workspace Rb1MSROW.wsp and application Rb1toMselfReqApp in Appendix C, “Downloadables, ConfigMaps, Applications” on page 355.

Resource>>#updateIndex:in:startingAt:

>

updateIndex: aVersionIndex in: theIndexes startingAt: aLastIndex

"Add a version to be the last in the collection."

| index version targetIndex |

index := aLastIndex + 1.aVersionIndex key: index.version := aVersionIndex value.

version links do: [:aLink |(aLink isConnected and: [version hasPrecedenceOver: aLink])

ifTrue: [aLink targetCollection do: [:aTargetBo |

aTargetBo notNil & (aTargetBo ~~ version businessObject)ifTrue: [

(targetIndex := theIndexes at: aTargetBo ifAbsent: [nil]) notNil ifTrue: [

index :=self

updateIndex: targetIndexin: theIndexesstartingAt: index]]]]].

^index

392 Using VisualAge Smalltalk ObjectExtender

F.4 Non-Required, One-to-Xxx Association

ObjectExtender needs a little help to run one-to-xxx, non-required associations properly. You may either change the generated code—override a method or change the inheritance, or change the code generator to solve the problems.

For a sample with test scripts focusing on the one-to-one association, see workspace Rb1to1OW.wsp and application Rb1to1App in Appendix C, “Downloadables, ConfigMaps, Applications” on page 355.

Page 419: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

F.4.1 Forward: Nil-Ability

In a department you can set an unset manager and replace a set manager with another manager, but you cannot set a manager nil (for example in 7.6.1, “Set up Sample Objects” on page 148, CLEANUP part). In that case the foreign key has to be updated with NULL. When it comes to getting the foreign key value for the update, the key is taken from the dataObject, and the dataObject is and must be still the read value. The required change is in the generated code. You can either zap ObjectExtender’s model code generation code (Figure 222), or zap the generated model code manually after each generation (Figure 223).

StRelationshipClass>>#addGetForwardKey

>>>>>>>>>>

addGetForwardKey

| method source template |

method :=(StMethod new: ’primGetForwardKeyForLink:’ parms: #(’aLink’))

methodComment: ’Get the forward key value to populate the passed link’;setPublic;addCategory: ’accessing’;yourself.

"template := ’ ^aLink source %1’."

"Get NULL key column(s) for nil set 1:1 links."template := (WriteStream on: String new)

cr; tab; nextPutAll: ’| key |’;cr; tab; nextPutAll: ’key := aLink source %1.’;cr; tab; nextPutAll: 'aLink target isInitialTarget ifFalse: [’;cr; tab; tab; nextPutAll: ’key := key class new ].';cr; tab; nextPutAll: '^key';contents.

Some Survival Stuff 393

Figure 222. Zap of Non-Required One-to-One Associations Model Code Generator

> template := template bindWith: self associationEnd name , 'Key'.

source := method source.source nextPutAll: template.self addInstanceMethod: method

Page 420: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 223. Zap of Generated Non-Required One-to-One Associations Model Code

F.4.2 Backward: Individual Access Solution (Overriding)

Asking a non managing employee for the managed department (for example in “Finding the Department (If Any) an Employee Manages” on page 159) opens the debugger window (Figure 224).

Rb30DepartmentToManagerRelationship>>#primGetForwardKeyForLink:

>>

primGetForwardKeyForLink: aLink

"Get the forward key value to populate the passed link"

aLink target isInitialTarget ifFalse: [^aLink source managerKey class new ].

^aLink source managerKey

394 Using VisualAge Smalltalk ObjectExtender

Figure 224. Dubugger: Non Managing Rb30Employee>>#managedDepartment

Use the following four steps to fix this situation on flight by overriding the failing method in the generated model code class (see also F.4.3, “Backward: Generic Access Solution (New Inheritance)” on page 396):

Page 421: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

1. Get the Class: In the Debugger (Figure 224) select Rb30EmployeeToManagedDepartmentRelationship(Relationship) >>#objectForForeignKey:

2. from the stack (left middle list) and select Stack->Browse Receiver Class to open a Class Editor on the receiver class (Figure 225).

3. Get the Method: In the Class Editor select Methods->Visibility->To Named Class... and select the class Relationship in the selection dialog (Figure 226, left). Ensure that the Methods->Visibility->Show All Implementations and Categories->Select All By Default toggles are checked.

4. Override the Method: Now, in the Class Editor select the objectForForeignKey:(Relationship) method in the list, change the passage ...[self error: VapNoObjectFound]... (in the last line) to: ...[^nil "self error: VapNoObjectFound"]... as shown in Figure 225, save the method (by pressing Ctrl-S), choose the Rb30EmployeeToManagedDepartmentRelationship class in the save dialog (Figure 226, right side), choose the Not categorized category categorization, and close the Class Editor window.

Some Survival Stuff 395

Figure 225. Overriding #objectForForeignKey: Method Just Before Saving It

Page 422: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 226. Class for Method Visibility and Source, and Class for the Method Save

5. Resume the Execution: In the Debugger (Figure 224) select Rb30EmployeeToManagedDepartmentRelationship(Relationship) >>#fetchTargetForLink: from the stack (left middle list, just below the item that you selected in step 1) and select Stack->Browse Receiver Class to resume with a restart of the dedicated, newly created, no longer inherited Rb30EmployeeToManagedDepartmentRelationship >>#objectForForeignKey: method.

Wow! That’s IBM Smalltalk!

F.4.3 Backward: Generic Access Solution (New Inheritance)

We have recognized Appendix F.4.2, “Backward: Individual Access Solution (Overriding)” on page 394 that the implementers of ObjectExtender had decided how the objectForForeignKey: method of the Relationship class should work. We decided that if no such object existed, then an error should be asserted. We prefer to have nil returned. Therefore, the generic solution is to implement a subclass of the Relationship class with the single method objectForForeignKey:, and let the one-to-one relationships, for example, our employee-to-managed-department relationship in the samples inherit from it.

396 Using VisualAge Smalltalk ObjectExtender

We proceed as follows:

1. Create a new application to hold the new class. For the purposes of this sample, we named the application Rb99EnhancedRelationshipApp.

2. Create a new part in the application. The relevant New Part dialog, after completion, should look like Figure 227.

Page 423: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 227. New Part Dialog for the Rb99EnhancedRelationship Class

3. Remove all prerequisites in the Rb99EnhancedRelationshipApp except the VapTransaction. Use the Prerequisites dialog from the application pop-up menu in the VisualAge Organizer.

4. Create a new method objectForForeignKey: in this class with the code as shown in Figure 228, and assign it to the category hydrating.

Some Survival Stuff 397

Figure 228. Rb99EnhancedRelationship>>#objectForForeignKey: Method

5. Make the Rb99EnhancedRelationshipApp visible to the Rb31EmpDeptApp by adding it as a prerequisite for the application. When this has been done, the resulting prerequisites dialog should look

Page 424: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

like Figure 229. The relevant Prerequisites command is available on the Applications menu of the VisualAge Organizer. This step is essential for the next step.

Figure 229. Prerequisites for Rb99EmpDeptApp

6. Locate the Rb31departmentToManagerRelationship class in the Rb31EmpDeptApp and open it with the Script Editor. Change the class definition so that it is now a subclass of Rb99EnhancedRelationship rather than Relationship and save the changes.

When you have made all these changes, you are ready to try the test again, to check whether a department has a manager.

This solution comes with a warning: When we modify the script in Step 6 above, we are modifying automatically generated code. However, subsequent model code class regeneration is not affected, because the re-generation

398 Using VisualAge Smalltalk ObjectExtender

updates only the relationship class and does not change the inheritance of the class. However, you should always review the model definition if you regenerate the code, to ensure that the class inheritance hierarchy remains as we set it in Step 6.

F.5 SQL Execution Order in Multiple Table Inheritance Mapping

On multiple table inheritance mapping ObjectExtender generates as many SQLs as tables are involved in and for each of the basic operations, such as insert, update, and delete. If constraints for the root and leaf tables exist in

Page 425: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

the database, the execution order of the SQLs is relevant. If ObjectExtender generates them incorrectly, SQL errors -530 occur as printed in the System Transcript output below (running the test script in 12.1.4, “Test Single Table Inheritance Mapping Sample” on page 264 with basic trace):

===========================a Rb62Book(1)a Rb62Borrowed(1)- - - - - - - - - -a Rb62Book(1)a Rb62Borrowed(1)’>>>executing insert’>>>executing: INSERT INTO USERID.Rb62Book ( serialNumber, condition ) VALUES ( 1, NULL ) >>>executed without error’>>>executing insert’>>>executing: INSERT INTO USERID.Rb62Borrowed ( id, returnDate, startDate ) VALUES ( 1, {d ’1998-08-09’ }, {d ’1998-07-10’ } ) >>>executed with error: [SQLSTATE=23503 - [IBM][CLI Driver][DB2/NT] SQL0530N The insert or update value of the FOREIGN KEY "USERID.RB62BORROWED.BORROWEDTOSTATUS" is not equal to any value of the parent key of the parent table. SQLSTATE=23503 [Native Error=-530]]

>>>executing: INSERT INTO USERID.Rb62Status ( id, type, bookSerialNumber, customer ) VALUES ( 1, ’Borrowed’, 1, 999 ) >>>executed with error: [SQLSTATE=23503 - [IBM][CLI Driver][DB2/NT] SQL0530N The insert or update value of the FOREIGN KEY "USERID.RB62BORROWED.BORROWEDTOSTATUS" is not equal to any value of the parent key of the parent table. SQLSTATE=23503 [Native Error=-530]]

Note: Borrowed is subclass of Status and the Status table is the parent table

Some Survival Stuff 399

(with the primary key) of the Borrowed table (with the foreign key). The primary key of the Borrowed table is also the foreign key. The entry in the table with the parent table has to be inserted first and deleted last in order to satisfy the constraints.

Either remove the constraints from the database or check and correct the sequence in the generated Query Pools in the services application. For the modifications see, for example, Figure 230. Note that indices in the argArray at: statements stay the same. Changing the Query Pools generation source code is not possible, because it is not available.

Page 426: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 230. SQL Sequence for Multiple Table Inheritance Mapping

For the sample in 12.2, “Multiple Table Inheritance Mapping” on page 269 the insertQuery:withInjector: and the deleteQuery:withInjector: methods of the following Query Pool classes in the Rb62LibraryServicesApp are affected:

• Rb62LibraryRb62AvailableQueryPool • Rb62LibraryRb62BorrowedQueryPool • Rb62LibraryRb62OverdueQueryPool • Rb62LibraryRb62ReservedQueryPool

400 Using VisualAge Smalltalk ObjectExtender

F.6 Transaction>>#hasModifications Support

The Transaction and BusinessTransaction of the current version of ObjectExtender have no #hasModifications support to use, for example, trigger a message such as Unsaved Changes. Save?—Yes/No/Cancel. A few changes to the classes in the modification notification chain make this very useful support available. The Transaction>>#hasModifications support is used, for example, in the Rb30DepartmentDetailView and Rb30EmployeeDetailView in 7.7.3, “GUI with List and Detail Views Supporting Drag and Drop” on page 170.

Page 427: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 231 gives an overview of a modification notification chain. A modification of an attribute of a business object version performs a modification level increment, which is promoted up to the transactions as versionChanged. The versionChanged method in the transactions asks for the read-only attribute hasModifications by drilling to the version object and reporting the result with the hasModification event.

Figure 231. Sequence of a Modification Notification

Table 102 through Table 103 show the new (N) and modified (M) methods to support the hasModifications on the BusinessTransaction and the Transaction. The new methods are in the newly created OERedbook category; the modified methods are in the newly created OERedbook-changed category.

Note that both the Transaction class and the BusinessTransaction class must define the read-only attribute hasModifications(Boolean) with the event selector in their public interfaces. See, for example, the hasModifications attribute definition of the Transaction public interface in Figure 232.

BusinessTransaction Transaction View Version

hasModificationshasModifications hasModifications isModified1 1 1 1 1 n

incrementModificationLevel

2. Event hasModificaitons 1. Object Modification

versionChangedversionChanged versionChanged

invokesfires event hasModifications

with read-only attributehasModifications

Some Survival Stuff 401

Page 428: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 99. New Transaction Methods to Notify Modifications

Table 100. New and Modified TransactionView Methods to Notify Modifications

Table 101. Modified Version Method to Notify Modifications

Transaction>>#methods (N=New, M=Modified)

N versionChanged

self signalEvent: #hasModificationswith: self hasModifications

N hasModifications

view notNil ifTrue: [^view hasModifications].^false

TransactionView>>#methods (N=New, M=Modified)

N versionChanged

transaction notNil ifTrue: [transaction versionChanged]

N hasModifications

self versions do: [ :v |v isModified ifTrue: [^true] ].

^false

M

>

primAddVersion: aVersion"Add a version into the view"

self versions at: ( self versionIdentifierFor: aVersion ) put: aVersion.self versionChanged.^aVersion

Version>>#incrementModificationLevel (M=Modified)

M incrementModificationLevel

402 Using VisualAge Smalltalk ObjectExtender

>>

modificationLevel := modificationLevel + 1.view notNil ifTrue: [view versionChanged]

Page 429: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 102. New and Modified BusinessTransaction Methods to Notify Modifications

BusinessTransaction>>#methods (N=New, M=Modified)

N hasModifications

transaction notNil ifTrue: [^transaction hasModifications].^false

M

>

generateTransactionFollowingCommitOrRollback

"Following our transaction signalling that it was the root of a commitor rollback ( i.e. not committed or rolledback as part of a cascadewe need to re-generate our transaction"

self generateTransaction ;attachDependenciesToTransaction ;signalEvent: #transaction with: transaction

M

>>

transaction

transaction isNil ifTrue: [ self

generateTransaction ;attachDependenciesToTransaction ;signalEvent: #transaction with: transaction. ].

^transaction

M attachDependenciesToTransaction

"A committed or rolledback transaction has to be replaced by a one"

transaction notNil ifTrue: [ transaction abtWhen: #rootCommittedOrRolledback perform: (

DirectedMessage newreceiver: self ;

Some Survival Stuff 403

>>>>>>

selector: #transactionWasCommittedOrRolledback: ;arguments: ( Array with: nil ) ).

transaction abtWhen: #hasModifications perform: (DirectedMessage new

receiver: self ;selector: #signalEvent:with: ;arguments: ( Array with: #hasModifications with: nil ) ) ]

Page 430: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Table 103. New and Modified TransactionView Methods to Notify Modifications

TransactionView>>#methods (N=New, M=Modified)

N versionChanged

transaction notNil ifTrue: [transaction versionChanged]

N hasModifications

self versions do: [ :v |v isModified ifTrue: [^true] ].

^false

M

>

primAddVersion: aVersion"Add a version into the view"

self versions at: ( self versionIdentifierFor: aVersion ) put: aVersion.self versionChanged.^aVersion

404 Using VisualAge Smalltalk ObjectExtender

Figure 232. Public Interface: hasModifications Attribute of Transaction

Page 431: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

F.7 Transaction Name Form

Figure 233 shows the Rb99TransactionForm in the Rb99OeUtilityViewApp. This form is very helpful when tracking transactions. If the transaction has no name set by the application, it displays its basicHash. The transaction(self) variable is the promoted part feature to make the connections to either a transaction itself or to the transaction feature of the BusinessTransaction. The Rb99TransactionForm is used, for example, in the Rb30DepartmentDetailView and Rb30EmployeeDetailView in 7.7.3, “GUI with List and Detail Views Supporting Drag and Drop” on page 170.

Figure 233. Form with Script to Display the Transaction Name

F.8 List Connections Utility

Throughout this book we used our own DfksListConnectionsView (Figure

Some Survival Stuff 405

234) tool in the DfksListConnectionsApp application to capture the connections of a part and display them in tabular form. In Figure 235 it shows its very own connections. Mark and copy the connection descriptions in the text pane to paste them in your documentation tool.

Page 432: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Figure 234. DfksListConnectionsView in Composition Editor

Figure 235. DfksListConnectionsView at Runtime Listing Its Own Connections

406 Using VisualAge Smalltalk ObjectExtender

Page 433: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Appendix G. Special Notices

This publication is intended to help application developers understand and use the ObjectExtender feature of the IBM VisualAge Smalltalk Enterprise product family. The information in this publication is not intended as the specification of any programming interfaces that are provided by the IBM VisualAge Smalltalk Enterprise product family. See the PUBLICATIONS section of the IBM Programming Announcement for the IBM VisualAge Smalltalk Enterprise product family for more information about what publications are considered to be product documentation.

References in this publication to IBM products, programs or services do not imply that IBM intends to make these available in all countries in which IBM operates. Any reference to an IBM product, program, or service is not intended to state or imply that only IBM’s product, program, or service may be used. Any functionally equivalent program that does not infringe any of IBM’s intellectual property rights may be used instead of the IBM product, program or service.

Information in this book was developed in conjunction with use of the equipment specified, and is limited in application to those specific hardware and software products and levels.

IBM may have patents or pending patent applications covering subject matter in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to the IBM Director of Licensing, IBM Corporation, 500 Columbus Avenue, Thornwood, NY 10594 USA.

Licensees of this program who wish to have information about it for the purpose of enabling: (i) the exchange of information between independently created programs and other programs (including this one) and (ii) the mutual use of the information which has been exchanged, should contact IBM

© Copyright IBM Corp. 1999 407

Corporation, Dept. 600A, Mail Drop 1329, Somers, NY 10589 USA.

Such information may be available, subject to appropriate terms and conditions, including in some cases, payment of a fee.

The information contained in this document has not been submitted to any formal IBM test and is distributed AS IS. The use of this information or the implementation of any of these techniques is a customer responsibility and depends on the customer’s ability to evaluate and integrate them into the customer’s operational environment. While each item may have been reviewed by IBM for accuracy in a specific situation, there is no guarantee

Page 434: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

that the same or similar results will be obtained elsewhere. Customers attempting to adapt these techniques to their own environments do so at their own risk.

Any pointers in this publication to external Web sites are provided for convenience only and do not in any manner serve as an endorsement of these Web sites.

The following terms are trademarks of the International Business Machines Corporation in the United States and/or other countries:

The following terms are trademarks of other companies:

C-bus is a trademark of Corollary, Inc.

Java and HotJava are trademarks of Sun Microsystems, Incorporated.

Microsoft, Windows, Windows NT, and the Windows 95 logo are trademarksor registered trademarks of Microsoft Corporation.

PC Direct is a trademark of Ziff Communications Company and is usedby IBM Corporation under license.

Pentium, MMX, ProShare, LANDesk, and ActionMedia are trademarks orregistered trademarks of Intel Corporation in the U.S. and othercountries.

UNIX is a registered trademark in the United States and other

IBM VisualAgeDB2

408 Using VisualAge Smalltalk ObjectExtender

countries licensed exclusively through X/Open Company Limited.

Other company, product, and service names may be trademarks orservice marks of others.

Page 435: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Appendix H. Related Publications

The publications listed in this section are considered particularly suitable for a more detailed discussion of the topics covered in this redbook.

H.1 International Technical Support Organization Publications

For information on ordering these ITSO publications see “How to Get ITSO Redbooks” on page 411.

• Using VisualAge UML Designer, SG24-4997

• VisualAge Java - RMI - SmalltalkThe ATM Sample from A to Z, SG24-5418

H.2 Redbooks on CD-ROMs

Redbooks are also available on CD-ROMs. Order a subscription and receive updates 2-4 times a year at significant savings.

CD-ROM Title Subscription Number

Collection Kit Number

System/390 Redbooks Collection SBOF-7201 SK2T-2177Networking and Systems Management Redbooks Collection SBOF-7370 SK2T-6022Transaction Processing and Data Management Redbook SBOF-7240 SK2T-8038

Lotus Redbooks Collection SBOF-6899 SK2T-8039Tivoli Redbooks Collection SBOF-6898 SK2T-8044AS/400 Redbooks Collection SBOF-7270 SK2T-2849

RS/6000 Redbooks Collection (HTML, BkMgr) SBOF-7230 SK2T-8040RS/6000 Redbooks Collection (PostScript) SBOF-7205 SK2T-8041RS/6000 Redbooks Collection (PDF Format) SBOF-8700 SK2T-8043

© Copyright IBM Corp. 1999 409

Application Development Redbooks Collection SBOF-7290 SK2T-8037

Page 436: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

410 Using VisualAge Smalltalk ObjectExtender

Page 437: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

How to Get ITSO Redbooks

This section explains how both customers and IBM employees can find out about ITSO redbooks, CD-ROMs, workshops, and residencies. A form for ordering books and CD-ROMs is also provided.

This information was current at the time of publication, but is continually subject to change. The latest information may be found at http://www.redbooks.ibm.com/.

How IBM Employees Can Get ITSO Redbooks

Employees may request ITSO deliverables (redbooks, BookManager BOOKs, and CD-ROMs) and information about redbooks, workshops, and residencies in the following ways:

• Redbooks Web Site on the World Wide Web

http://w3.itso.ibm.com/

• PUBORDER – to order hardcopies in the United States

• Tools Disks

To get LIST3820s of redbooks, type one of the following commands:

TOOLCAT REDPRINT TOOLS SENDTO EHONE4 TOOLS2 REDPRINT GET SG24xxxx PACKAGE TOOLS SENDTO CANVM2 TOOLS REDPRINT GET SG24xxxx PACKAGE (Canadian users only)

To get BookManager BOOKs of redbooks, type the following command:

TOOLCAT REDBOOKS

To get lists of redbooks, type the following command:

TOOLS SENDTO USDIST MKTTOOLS MKTTOOLS GET ITSOCAT TXT

To register for information on workshops, residencies, and redbooks, type the following command:

TOOLS SENDTO WTSCPOK TOOLS ZDISK GET ITSOREGI 1998

• REDBOOKS Category on INEWS

• Online – send orders to: USIB6FPL at IBMMAIL or DKIBMBSH at IBMMAIL

© Copyright IBM Corp. 1999 411

For information so current it is still in the process of being written, look at "Redpieces" on the Redbooks Web Site (http://www.redbooks.ibm.com/redpieces.html). Redpieces are redbooks in progress; not all redbooks become redpieces, and sometimes just a few chapters will be published this way. The intent is to get the information out much quicker than the formal publishing process allows.

Redpieces

Page 438: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

How Customers Can Get ITSO Redbooks

Customers may request ITSO deliverables (redbooks, BookManager BOOKs, and CD-ROMs) and information about redbooks, workshops, and residencies in the following ways:

• Online Orders – send orders to:

• Telephone Orders

• Mail Orders – send orders to:

• Fax – send orders to:

• 1-800-IBM-4FAX (United States) or (+1) 408 256 5422 (Outside USA) – ask for:

Index # 4421 Abstracts of new redbooksIndex # 4422 IBM redbooks

In United StatesIn CanadaOutside North America

IBMMAILusib6fpl at ibmmailcaibmbkz at ibmmaildkibmbsh at ibmmail

[email protected]@[email protected]

United States (toll free)Canada (toll free)

1-800-879-27551-800-IBM-4YOU

Outside North America(+45) 4810-1320 - Danish(+45) 4810-1420 - Dutch(+45) 4810-1540 - English(+45) 4810-1670 - Finnish(+45) 4810-1220 - French

(long distance charges apply)(+45) 4810-1020 - German(+45) 4810-1620 - Italian(+45) 4810-1270 - Norwegian(+45) 4810-1120 - Spanish(+45) 4810-1170 - Swedish

IBM PublicationsPublications Customer SupportP.O. Box 29570Raleigh, NC 27626-0570USA

IBM Publications144-4th Avenue, S.W.Calgary, Alberta T2P 3N5Canada

IBM Direct ServicesSortemosevej 21DK-3450 AllerødDenmark

United States (toll free)CanadaOutside North America

1-800-445-92691-800-267-4455(+45) 48 14 2207 (long distance charge)

412 Using VisualAge Smalltalk ObjectExtender

Index # 4420 Redbooks for last six months

• On the World Wide Web

Redbooks Web SiteIBM Direct Publications Catalog

http://www.redbooks.ibm.comhttp://www.elink.ibmlink.ibm.com/pbl/pbl

For information so current it is still in the process of being written, look at "Redpieces" on the Redbooks Web Site (http://www.redbooks.ibm.com/redpieces.html). Redpieces are redbooks in progress; not all redbooks become redpieces, and sometimes just a few chapters will be published this way. The intent is to get the information out much quicker than the formal publishing process allows.

Redpieces

Page 439: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

IBM Redbook Order Form

Please send me the following:

Title Order Quantit

First name Last name

Company

Address

City Postal code

Telephone number Telefax number VAT number

Country

413

We accept American Express, Diners, Eurocard, Master Card, and Visa. Payment by credit card notavailable in all countries. Signature mandatory for credit card payment.

Invoice to customer number

Credit card number

Credit card expiration date SignatureCard issued to

Page 440: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

414 Using VisualAge Smalltalk ObjectExtender

Page 441: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Glossary

ACID. A mnemonic for the properties a transaction should have to satisfy the Object Management Group Transaction Service specifications. A transaction should be Atomic, its result should be Consistent, Isolated (independent of other transactions) and Durable (its effect should be permanent).

atomic. An atomic database transaction is one which is guaranteed to complete successfully or not at all. In an error prevents a partially-performed transaction from proceeding to completion, it must be backed-out to prevent the database from being left in an inconsistent state.

broken mapping. An inconsistent mapping, for example, caused by overlays.

business object (BO). This term denotes the objects in your problem domain that you wish to persist in a data store.

cardinality. Cardinality expresses the constraints on the number of instances that are related through a relationship.

code-generation. The function whereby code is generated automatically given certain specifications.

collision. A collision between transaction occur, when they try to commit changes on the same objects or data.

concurrence. Concurrence is the situation, when two or more program are changing the same objects or data at the same time.

© Copyright IBM Corp. 1999

connect/disconnect. The attachment (or unattachment) of a target business object to/from a link.

consistency. In the context of ACID: a transaction is a correct transformation of the state. The actions taken as a group do not violate any of the integrity constraints associated with the state. This requires that the transaction be a correct program.

CRUD. Create/Read/Update/Delete, the four basic types of operations on database rows,

records. ObjectExtender provides these operations on objects as well.

data definition language (DDL). A language enabling the structure and instances of a database to be defined in a human- and machine-readable form.

data model. The term, data model is used here, to make a distinction between it and an object model that you wish to persist. For example, the schema for a relational database represents the data model. Your object model is represented differently and will not need to be tightly coupled with the data model representation.

data object (DO). Data objects contain the data for the business objects. The data is in the form in which it was retrieved from the data store.

durability. In the context of ACID: Once a transaction completes successfully (commits), its changes to the state survive failures.

framework. In object-oriented systems, a set of classes that embodies an abstract design for solutions to a number of related problems.

headless. without a user interface.

home collection. Home collections provide the logical home for business objects. They provide APIs for creating or locating instances.

hydration. The activity of populating the properties and relationships of a model object.

isolation. In the context of ACID: even though transactions execute concurrently, it appears to

415

each transaction, T, that others executed either before T or after T, but not both.

link. The infrastructure that connects source and target business objects in a relationship.

metadata. Any information which describes according to prescribed specification a target data.

multiplicity. See cardinality.

nested transaction. A nested transaction is a tree of transactions, the sub-trees of which are

Page 442: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

either nested or flat transactions. Transactions at the leaf level are flat transactions. The transaction at the root of the tree is called the top-level transaction; the others are called subtransactions. A transaction’s predecessor in the tree is called a parent; a subtransaction at the next lower level is also called a child. A subtransaction can either commit or roll back; its commit will not take effect though, unless the parent transaction commits. Therefore, any subtransaction can finally commit only if the top-level transaction commits. The rollback of a transaction anywhere in the tree causes all its subtransactions to roll back.

object model. Object model is to data model what a hierarchy of classes is to a schema of database tables. It is simply a distinction between the two representations of how the data is represented.

object-oriented. Can apply to analysis, design, and programming disciplines.

persistence. A property of a programming language where created objects and variables continue to exist and retain their values between runs of the program. This is in contrast to transient objects that cease existing when the application that created them is not running.

pre-fetch. The notion of defining a path to set of data that you want to preload from data store to object model to reduce the number of database trips improving performance.

relationship. As understood in the context of the ObjectExtender framework, a relationship is an instance variable in a business object which

416 Using VisualAge Smalltalk ObjectExtender

contains a reference to another persistent object.

transaction. A unit of interaction with a DBMS or similar system. It must be treated in a coherent and reliable way independent of other transactions.

Page 443: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

List of Abbreviations

ACID Atomic/Consistent/Isolated/ Durable

API Application Programming Interface

BLOB Binary Large Object

BO Business Object

CLI Command Language Interface

CRUD Create/Read/Update/Delete

DB Database

DBMS Database Management System

DDL Data Definition Language

DO Data Object

GIF Graphic Interchange Format

GUI Graphical User Interface

IBM International Business Machines Corporation

IDE Integrated Development Environment

ITSO International Technical Support Organization

ODBC Opend Database Connectivity

OE ObjectExtender

OO object-oriented

SQL Structured Query Language

TRX Transaction

© Copyright IBM Corp. 1999

UDB Universal Database

UML Unified Modeling Language

VA VisualAge

VAP VisualAge Persistence

417

Page 444: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

418 Using VisualAge Smalltalk ObjectExtender

Page 445: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Index

Symbols#abtRemove 305#allInstances 267, 277, 341#areForeignKeysValid 145, 389#basicHash 405#canMergeWith: 332#commitWhenFailureDo: 332#deleteAssociation 389#hasModification support 178#hasModifications 190, 400#manyQueryUsing:with: 281#markRemoved 249#maximumLength 131#openedWidget 328#referenceAttributeName 172#referenceString 164, 170#setToCompleted 281#singleQueryUsing:with: 281#validationError 97#vapAsSQLStringFor: 281#xyzReferenceString 170(a) attribute

property 203property map 33, 205

(r) association (relationship)property 203property map 33, 205

<default> superclass 260<not mapped> 207

Numerics1999..., Y2K 265, 2662000, Y2K 265, 266

© Copyright IBM Corp. 1999

Aabbreviations 417abstraction levels for data 15abstraction of data 15access

backward 148control 15database 270optimize 35speed 270

speed of database with inheritance 259tune 19

ACID 312acronyms 417activate

data store 35, 227, 232menu 75

active transaction 11add

attribute 218foreign key relationship 197method 218method to home collection class 279public interface 218service to the service object 280SQL query string to query pool 279

add... method 136adjust

many 203navigable 203physical name 143schema 197

administrator, database administrator 62, 146allInstances 116, 277

inspect 124allow nulls 145alternative 22application 8

behavior on changes 326contains all model code 135contains part of the model code 135context 28data 15develop 19download 355

419

extension 19image 15initial version 19name 41, 135, 300name for map storage 230name for services 69prerequisite 136rapid development 19real world 14, 332script 15

application layers in ObjectExtender 5application name

Page 446: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

for model code 54for services 112

application prerequisites for metadata storage 354

application programming layer 5approach to inheritance 258appropriate

single table inheritance map 259value for discriminator 263

argument, name of argument 136artificial object ID 259aspect, behavioral aspect 257association 4, 7, 127

among classes 14class 136, 203, 241define 129, 299direction 132display object 214editor 8, 24, 129, 132, 203forward 203, 207generate model code 135inheritance 257many 131many-to-many 241map 10, 230map to foreign key relationship 230name 129navigable 131, 203nil-able 231non-required 231not mapped 207one-to-many 7one-to-one 7, 231one-to-xxx 203page 205page of property map editor 230property map editor 33

editor 24, 51for convenience 164map 64, 229map to column 229name 50, 109new 51non business for predicate 333page of property map editor 229property 52property map editor 33public interface 214read-only 161reference 170relational 134separate table 269timestamp 334transaction of variable 328value 38value not required 203vs. behavior for inheritance 259

attribute property map editor 33automatic naming 109

Bbackward

access 148non-required one-to-one relationship 394, 396path 19, 20, 105, 195

basic trace 37, 280basicHash for transaction ID 405be part of optimistic predicate 332behavior

desired for changes 326for transactions last wins 332vs. attributes for inheritance 259

420 Using VisualAge Smalltalk ObjectExtender

reference 164related method 136required 131required self-association 391role 4, 131self 148unfinished 389

attach transaction framework 83attribute

business logic for collision 333class 9, 14, 203, 205define 50, 128, 299

behavioral aspect 257bidirectional

navigable 203navigable relationship 156

bill of material 42binary large object 337BLOB 337

create view with BLOB 345database 337DB2 342mixed media 337picture 337

Page 447: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Smalltalk 342static query 342voice 337

bottom-up 19, 20combined with top-down 22path 105, 195, 227

brokenmap 205, 229property map 389

browse data 12browser 14

documentation 22map 9, 15, 22, 32, 64, 110, 210, 227model 7, 14, 22, 24, 47, 49, 127, 203, 209, 260overview 23refresh 17schema 8, 15, 22, 27, 61, 106, 109, 146, 198, 344status 35, 75, 87, 113, 123tool 6

businessobject 343rule 14transaction 87, 296

business class, generate business class 20business logic defines attributes for predicate

333business object 6, 7, 9

definition 5generate class 19locking 326relationship 5transacted 328version 39

businessTransaction 87, 95, 119part in view 90

system diagram 385use case 381, 382use case diagram 385

chaingeneration 137of modification notification 401

changeclass 54column type 143, 389dirty 268key column type 144manual 20merge 13name 205parallel 326SQL in query pool 334superclass 354type 143, 144uncommitted 325

changesconcurrent 331unsaved 190, 400visibility anywhere else 326

characters allowed in name 29check

consistency 389foreign key relationship consistency 145

check-out 19child transaction 12, 287, 325, 328circular reference 147class

association 14, 136, 203, 241attribute 9, 14, 203, 205change 54create 7define 49, 128, 299diagram 4, 47, 129, 227, 257

421

Ccache, clear relationship cache 35capture

database schema 20model 19schema 20

cardinality 242default 203

case studyconcept 378requirement 378

discriminator 258edition 16editor 24, 49, 244, 260editor (lite collection) 342generate 6, 19generate model code 136helper for queries 281hierarchy 55, 257home 136inheritance 257key 136leaf 398

Page 448: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

metadata storage 16, 17model 54, 136, 354model code 54, 354name 49, 199, 354name for map storage 230new 49, 54new created 57object 14persistent 64, 229query pool service 279root 398service 279services 58, 111, 210storage 37VisualAge editor 37

class diagram for library 44, 387class editor, edit model class 24class generate 20class, domain class 11cleanup 35cleanup menu 75clear

home collection cache 35local image data store 61, 75

cluster map with no inheritance 228, 272cluster name 354code

application 15for data access 19generate 15set generation option in model 54, 354to add a method to a query pool 279to add a method to the service object 280to add for dealing with locked objects 335to delegate work to service object 279to generate omitting time stamp 334to insert a record into the database 74

detect 332detect in image 326detection in the image 326detection on the backend data store 332exception block 332merge 13of concurrent transactions 325of transactions, definition 326resolution 333resolution implementation 332rollback 13SQL error 333transaction 11

collision managementoptimistic 11pessimistic 11

column 28additional for inheritance 261change type 143, 389define type 229discriminator 261, 272edit 30editor 62, 141foreign key relationship 144key 140, 144, 197map 10, 229map to attribute 229name 109, 140NOT NULL 145primary key 108, 197relationship 144table 9type 62, 139, 143, 229type for foreign key 390type for primary key 390

column, delete 140combination of bottom-up and top-down 22

422 Using VisualAge Smalltalk ObjectExtender

to insert current time stamp 334to make retrieved object accessible 280to notify association object removal 249to query for multiple objects, corrected 281to return exact result set 278

collectmethod to collect the result 280query result 279

collectionhome 277, 341lite 26, 337, 340, 341

collision

combo box 86, 99comment in storage class 37commit 13, 120

database 317error 330nested transaction 330top-level transaction 326transaction 268

compare before write 65compatible type 229complete

generation 137

Page 449: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

instantiation 26complex

dependencies among tables 20model 19

composition editor 247, 337concept

case study 378ObjectExtender 3object-oriented 257

conclusionof your first samples 237top-down 102

concurrent 65changes 331overwrites 123transaction 325

configuration map, downloadable 355confirm delete 120conflict 65

of concurrent transactions 325transaction 11

conformname 140physical name 140

connectiondatabase 112, 146, 190information 146, 190part 84to database locked 268to physical database 6

connection list utility 405connection type of database 190consider

direction for update 268navigation 268user interface 12

consideration along outside-in path 22

contextapplication 28naming 28of a transacted variable 328transaction 38, 116

control, access control 15convenience

add... method 136attribute 164method 136, 164remove... method 136

convenience method 161convention

freedom 22name 351, 353naming 41, 50

convert image to string 337converter

type 30converter, VapConverter 61, 62cooperative work 22copy from data object 326copy-on-read 326correct model code 137, 231cost 278create

child transaction 328class 7constraint 146CRUD 115, 214DDL 8image schema 139key 146map 9, 228model 47, 128, 227model manually 227object 248

423

consistencycheck 389check keys 389responsibility 389

consistent 15foreign key relationship 145unit of work 5

constraintcreate 146database 8, 130, 231in database 197, 198, 398name 140

part 337re-create transaction tree 286schema 8table 146table map 228view with BLOB 345view with lite collection 342

CRUDcreate, read, update, delete 115, 214

CURRENT TIMESTAMPin insertSqlString,updateSqlString 334in SQL 334

Page 450: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

current transaction 13custom query 277customize naming 29

Ddata 5

abstraction 15abstraction level 15application 15browse 12source 106

data accesscode 19optimize 35programming layer 5

data entry error 97data entry view 119data object, copy business object from 326data store 11, 15

activate 35, 227, 232backend detects collision 332clear 61, 75dump to file 20framework 15generate 227image 138in image 20load from file 20map 210, 230map metadata 16map new 227name 210physical 15view 15

database 3, 6, 19, 20access 270

legacy 9physical 6, 8, 61, 69relational 4, 8, 15, 19, 257sample 105, 195schema 8, 32source 231table 5, 8, 9, 146timestamp for collision detection 334tune access 19use CURRENT TIMESTAMP for collision de-tection 334

database schemacapture 20import 20map to model 19, 22

DB2 3, 105, 195, 231BLOBs 342naming limitations 244

DDL 15create 8generate 19, 146, 198SQL 146

debug session 35debugger

fix method in debugger 394model editor 389standard 77

defaultcardinality 203direction 203generate default scripts 338many 203mapping 64navigable 203not required 203repeatable-read 326

deferred write schema 11

424 Using VisualAge Smalltalk ObjectExtender

administrator 62, 146BLOB 337commit 317connection 112, 146, 190connection type 190constraint 8, 130, 197, 198, 398constraints 231existing 9generate physical 145in image 69index 8in-image 61

defineassociation 129, 299attribute 50, 128, 299class 49, 128, 299foreign key 9foreign key relationship 197, 271map 244, 262, 341map for inheritance 272model 14, 47, 127, 227, 241, 259, 270, 298, 341object model 14public interface 337

Page 451: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

relationship 54, 271schema 244, 260, 270, 341schema manually 227

define primary key 197definition

business object 5collision of transactions 326

delete 12broken property map 208column 140confirm 120CRUD 115, 214foreign key column 140foreign key relationship 140row from table 268

demonstration purpose 20department 41derive

information 10reference 161

design 15, 22object-oriented 19state pattern 257

desired behavior on changes 326detail

hide implementation details 305trace 114, 274, 280type details 30view 122

detail view 119drag-drop support 176

detectcollision 332collision by SQL error 333collision in image 326collision on back-end data store 332

develop

diagram, class diagram 4, 129, 227, 257difficult mapping 22direct edit 51direction

association 4, 132consider for update 268default 203navigable 7, 203navigate 211

dirtychange 268object 268

discard object version 13discriminator

appropriate value 263class 258column 261, 272inheritance 258note 263object 258row 258subclass 258value 263write 263

displayassociated object 214reference 170, 214transaction name 405

divide (large) transaction 12documentation

browser 22textual summary 22

domainclass 11

download 355downloadable 392drag-drop support

425

application 19from scratch 19

developer of the edition 16development 19

environment 6integrate 57path 19, 47, 105, 127, 195, 227repository 17scenario 3tasks 14time 6

development from scratch 8

detail view 176list view 170reusable form 171single reference 171view 170

drag-source 190drag-target 190drawback of single table inheritance map 258dropped event 191drop-target 190dump data store to file 20duplicate key error 267

Page 452: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

dynamicchange of locking strategy 325SQL 342

Eedit

column 30direct 51indirect 51parallel 326role name 203

editionclass 16developer 16load 16

editor 22association 8, 24, 129, 132, 203attribute 24, 51class 24, 49, 244, 260class (lite collection) 342column 62, 141composition 247foreign key relationship 9, 28, 141interface 337map 10, 205model 205property map 10, 64, 229property.map 33public interface 164, 247, 337superclass 260table 62, 108, 197VisualAge class 37VisualAge scripts 37

editor composition 337employee 3, 41

top-down 47

...does not understand ...Key 138cannot change its superclass to... 354data entry 97database 100empty key descriptor 109handling from input 97Input argument size does not match query string 335map 205message prompter 99meta data validation 207, 229missing object identifier 52on nested transaction commit 330SQL 100SQL -530, constraint violation with foreign key 399top-level transaction 100validation 97, 305

event signaling 165example, overview of examples in this book 351exception

collision 332locked object 335

exchange metadata 17execution order of SQLs 399existing database 9export

metadata 17schema to database 146

extension, application extension 19

Ffactory 252failure in merge 332failure in transaction 332file

426 Using VisualAge Smalltalk ObjectExtender

enableinspector 40pessimistic locking 66, 325

enablement for inspector 160enhanced inspector 39enhancedBusinessTransaction 87enhancement of transaction 400entity-relationship

inheritance 257model 257

environment, development environment 6error

download 355GIF 338load picture from file 345path 337

filterobjects in lite collections 341

fixbroken map 207method in debugger 394method on flight 394

focus on list entry in map 207foreign key 4, 9, 133, 137

Page 453: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

column type 390define 9map 9primary key 270relationship 14, 28set 136SQL error 399subclass table 270table 139, 144

foreign key columndelete 140

foreign key relationshipadd 197change name 261check consistency 145column 144consistent 145define 197, 271delete 140editor 9, 28, 141inconsistent 145inheritance 257map 230map to association 230schema 197side 207table 389

formmultiple reference 178reusable 170single reference 178

forwardassociation 203, 207nil-ability 148nil-ability of non-required one-to-one relation-ship 393path 19, 47, 127

implementation 22naming 22

front end 5future model code 203

Ggenerate

all model code into the same application 135business class 20business object class 19class 6, 19, 20code 15data store 227DDL 19, 146, 198default scripts 338framework 15image schema 57map 19, 20, 57, 109, 137, 138, 201, 227, 303metamodel 20model 14, 109, 201model code 56, 111, 135, 137, 209, 300model code for a class 136model code for an association 135model code in separate applications 54model code into separate applications 135persistent classes option 55physical database 145result 19schema 19, 57, 61, 137, 138, 139, 260, 302script 15selectively 54service classes 111, 210services 137, 146, 304services classes 20, 32, 69, 146, 231setter 39SQL 146

427

relationship 137, 231framework

attach transaction 83data store 15generate 15mapping 15modeling 14ObjectExtender 14relationship 14transaction 15, 83

freedomconvention 22

static query 342VisualAge parts option 55

generationchain 137complete 137incomplete 138model code options 209option for services 69options for model code 54, 354sequence 137services classes option 210

generation option

Page 454: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

model code 111, 135services classes 146

getter 136generate 39

GIF 337file 338

global reset in ObjectExtender 35global shared transaction 11good practice 161

separate model from implementation 270graphic interchange format 337GUI 83, 101, 115, 161, 170, 214

local image schema 101of many-to-many association sample 251single-window 161test 122transaction save 190

HhasModifications 190, 317hasModifications support 400headless 309

test 113, 146, 211, 246, 264, 273, 282, 309heavy row 26Heisenberg, Karl Werner (1901-1976) 39helper used for queries 281hide

implementation details 305implementation details of many-to-many as-sociations 246

hierarchyclass 257inheritance 257

high-level qualifier 62, 139, 145, 262home

add method 279

identifier of an object 52image 16

application 15convert to string 337data store 20, 101, 138detect transaction collision 326from file 337read 337

image data store application with GUI 101image schema 20

create 139generate 57

impedance gap between relational and object-ori-ented world 257

implementationfreedom 22hide details 305object-oriented 19part 338separate from model 270

importdatabase schema 20from legacy database 106metadata 17model 19, 227schema 20, 106, 196

incomplete generation 138inconsistency 389inconsistent foreign key relationship 145incorrect map 229index in database 8indicator

in row for class and vice versa 258indirect edit 51information

connection 146, 190derive 10

428 Using VisualAge Smalltalk ObjectExtender

class 136collection 341entry point for queries 279serving object 280transacted 116

home collection 277clear cache 35

host-variable syntax 279hydrate loaded metadata item 17

IIdentification of an object 244

inheritance 257all instances for single inheritance map 267approach 258association 257behavior vs. attribute 259class 257cluster map with no inheritance 228discriminator 258entity-relationship 257foreign key relationship 257hierarchy 257impedance gap 257

Page 455: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

insert before delete 267map 258map tree to table 260multiple table inheritance map 269, 276new for fixing 396performance 259primary key 267relationship 257root of hierarchy 262root of tree 262services 264, 273single table inheritance map 262special 19SQL queries 259subclass 257superclass 260

inheritance hierarchy to single table 258in-image database 61, 69initial version of an application 19initialize transaction 328insert 12

before delete in inheritance 267row into table 268user code 14

insertSqlString with CURRENT TIMESTAMP 334

inspectallInstances 124services classes 210

inspectorbasic 76enable 40enablement 123, 160enhanced 39intrusive 39, 40Smalltalk 38standard 77

public attribute 214user 5

intrude 39intrusive

inspector 40intrusive inspector 39isChanged support 123isolation

of a transaction 312Isolation Policies 325isolation policy 325isolation policy of transaction 325

JJava, VisualAge for Java Persistence Builder xxi

Kkey 9, 28, 50, 52, 108, 133, 137

class 136column 140, 144, 197consistency check 389empty key descriptor error 109for SQL query string 281foreign 4, 9foreign key relationship 14inconsistent keys 390multiple 259primary 50SQL error 399subclass table 270table 146

key columnchange type 144type 144

429

unintrusive 40instance, all for single table map inheritance 267instances, all 277instantiate

completely 26object 341partially 341

integrated development environment 57interested, notify interested parts 338interface

add public attribute 218editor 337

Llarge model 54large row set 26large table 278last wins, transaction behavior 332layer 5

application programming 5data access programming 5object modeling 5persistence 6services 6

lazy read 76, 77

Page 456: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

lazy set 77leaf

class 398table 398

legacydata access code 19database 5, 9, 19, 20

lengthcolumn length 62name 29

leveldata abstraction 15of nested transaction 13subtransaction 12trace 274

library 42scenario 41static class diagram 44, 387system overview 42use case 42

Library Management System 42limitations in naming 29list

for selection 115view 122

list view 116drag-drop support 170

lite collection 26, 337, 340, 341class editor 342performance 26, 341

loadavailable schema 139data store from file 20edition 16hydrate 17map 16metadata 16

pessimistic 65, 325, 335set strategy at runtime 325strategy 325

lock-on-read, pessimistic locking 335logging 36logical name 28, 139

Mmaintenance 54management schema for collisions 11manual 22

change 20create model 227define schema 227naming 109

manyadjust 203association 131default 203

many-element 136many-to-many

association 241association sample GUI 251hide implementation details 246

map 9, 258(a) attribute property 205(r) relation (association) property 205association 10, 230association to foreign key relationship 230attribute 64, 229attribute to column 229broken 205, 229broken property map 389browser 9, 15, 22, 32, 64, 110, 210, 227cluster map with no inheritance 262column 10, 229

430 Using VisualAge Smalltalk ObjectExtender

model 16picture from file 345refresh 17schema 16

local image data store 20local image schema application with GUI 101lock resource 11locked database connection 268locking 39

business object 326optimistic 65, 325, 326optimistic predicate 65

column to attribute 229crate 228create 9create for table 228data store 210, 230default 64define 244, 262, 341define for inheritance 272delete broken property mapping 208editor 10, 205error 205fix broken mappings 207

Page 457: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

foreign key 9foreign key relationship 230foreign key relationship to association 230generate 19, 20, 57, 109, 137, 138, 201, 227, 303incorrect 229inheritance 258load 16map entry in list has focus 207model 227model to database schema 19, 22model to schema 227name 300new for table 228of table 64property for subclass 263revert 17review 64save 69, 145, 230schema 227schema to model 227self-referencing entry 207table 229textual summary 208

mapping 5, 6, 15, 109difficult 22framework 15

maximum name length 29media BLOB 337menu

ObjectExtender tool menu 23merge

change 13collision 13failure 332first 39object version 13

repository 16, 17revert 17runtime 354save 16storage 16, 354storage class 16, 17validation error 207, 229

metamodel 16, 19generate 20model 227

method 339add 218add... 136convenience 136, 164convenient 161name 129, 136, 203override 394related association 136remove... 136reuse of collect the result 280

model 19association 389browser 7, 14, 22, 24, 47, 49, 127, 203, 209, 260capture 19class 54, 136, 354class editor 24class name 199class selection for generation 56code for classes 54, 354code storage application name 54complex 19correct code 231create 47, 128, 227define 14, 47, 127, 227, 241, 259, 270, 298, 341editor 205

431

merge policy 13message

prompter 99trace 56

metadata 16data store map 16exchange 17export 17import 17load 16model 15, 16, 47move 17

entity-relationship 257future code 203generate 14, 109, 201generate code 56, 209, 300import 19, 227large 54load 16map 227map to database schema 19, 22map to schema 227metadata 15, 16, 47metamodel 227

Page 458: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

model-view-controller 354MVC 354name 48, 109, 203, 300, 354new 47object 6, 7, 8, 14, 32re-generate 14release 60reuse 227revert 17review 203root of hierarchy/inheritance 262save 50, 60separate from implementation 270set code generation option in model 54, 354storage application name 48storage class name 48textual summary 24, 52, 109unfinished associations 389version 60

model codecorrect 137generate 111, 135, 137generation option 111, 135generation options 55re-generate 137review 136

model code generation 55model storage application name 110model storage class name 110model view controller 354modeling 5, 14

object-oriented 19, 20, 22modeling framework 14modeling tool, IBM VisualAge UML Designer 19modification

notification chain 401notify 400

multiplicity 242MVC 354

names in MVC layout 354

Nname

allowed characters 29application 41, 135, 300argument 136association 129attribute 50, 109change 205change for foreign key relationship 261class 49, 199, 354cluster 354column 109, 140conform 140constraint 140convention 351, 353data store 210for application services 69form to display transaction name 405in database 29length 29, 140logical 28, 139map 300map storage application 230map storage class 230method 129, 136, 203model 48, 109, 203, 300, 354model class 199model storage application 110model storage class 110MVC 354of services application 112physical 28, 130, 198

432 Using VisualAge Smalltalk ObjectExtender

record 11modify object 11monitor

headless test 75status browser 75test with GUI 122

move metadata 17multiple primary keys 259multiple reference

form 178multiple reference, and form 178multiple table inheritance map 269, 276, 398

prefix 354project 41, 354role 203, 208schema 106, 203, 300services classes 129storage 110suffix 354table 139, 140transaction 405

name length maximum 29naming

automatic 109

Page 459: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

context 28convention 41, 50customize 29freedom 22limitation 29manual 109pattern 7subclass 29support 142

natural object ID 259navigable 7

adjust 203association 131, 203bidirectional 203bidirectional relationship 156default 203direction 7, 203update 268

navigatedirection 211object 154object links 146, 211relationship path 14

navigationconsiderations 268test cases 156

nestedtransaction 12, 254, 325, 330transaction commit error 330transactions 283

nested transaction 317new

attribute 51class 49, 54data store map 227model 47table map 228

column 145required 145

notification chain for modifications 401notify

interested part 338modification 400

null 145

Oobject 5

add service 280binary large object 337business 343class 14create 248dirty 268display associated 214filter by lite collections 341ID 244identifier 52in transaction 11in transactions 325inheritance discriminator 258instantiate 341is locked exception 335model 6, 7, 8, 14, 32modify 11navigate 154navigate links 146, 211non-persistent 13participating in transaction 11picture 341refresh 11remove 305serving the home 279setup 146

433

new classes, creation of 56nil-ability

forward 148of forward, non-required one-to-one relation-ship 393

nil-able association 231non-persistent object 13non-required

association 231one-to-one association 392

not mapped 207NOT NULL

subset of information 341transacted 328transient 13version 13, 39

object IDartificial 259in subclass 259natural 259

object identifieralmost sacrosanct 237missing error 52

object model

Page 460: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

define 14layer 5

object modification 11object version

discard 13merge 13

ObjectExtender 3application layers 5concept 3framework 14global reset 35tools 23VisualAge Smalltalk xxi

object-oriented 3concept 257design 19implementation 19modeling 19, 20, 22view 7world 257

observe 39on flight fixing methods 394one-to-many

association 7relationship 131, 136, 241

one-to-one 5association 7association, non-required 392mapping 5relationship 137

one-to-one association 231one-to-xxx association 203optimistic

attributes for locking 332collision management 11locking 65, 325, 326predicate 192, 332

services generation 146order

of SQL executions 276organizer in VisualAge 17out of step 17output

system transcript 361outside transaction 325outside-in

consideration 22path 19, 22, 227

overqualified SQL 332override method 394overview

browser 23examples 351tool 23

overwrite, concurrence 65overwrite, concurrent 123

Ppackaging 354page

association 205for association in property map editor 230for attribute in property map editor 229

parallelchange 326child transaction 325edit 326transaction 325

parent transactionshared transaction 12top-level transaction 12

parse all instances 278part

434 Using VisualAge Smalltalk ObjectExtender

optimistic predicate, locking 65optimize

access 35data access 35

optiongenerate persistent classes 55generate services classes 210, 231generate VisualAge parts option 55model code generation 111, 135, 209root class for persistence 55

optionsfor model code generation 54, 354

connection list 84create 337implementation 338notify 338of predicate 332parts list 84

partial instantiation 341participating, object in transaction 11parts list 84pass top-level transaction 328path

backward 19, 20, 105, 195

Page 461: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

bottom-up 105, 195, 227development 19, 47, 105, 127, 195, 227file 337forward 19, 47, 127navigate 14outside-in 19, 22, 227top-down 47, 127, 227

patternnaming 7state 257

performance 268, 278access 341inheritance 259lite collection 26, 341trade-off vs. resource 270

Persistence Builder, VisualAgefor Java, Persistence Builder xxi

persistence framework, effect of 83persistence layer 6persistent 6

class 64, 229object version 13

persistent classesgeneration option 55

persistent classes generation option 55persistent storage 13pessimistic

collision management 11locking 65, 325, 335locking enable 66, 325lock-on-read 335

physical 6data store 15database 8, 61, 69name 28, 130, 198

physical nameadjust 143

printable reference string 161separation model from implementation 270

precompile SQL 342predicate

for optimistic locking 332non business attribute 333optimistic 192, 332timestamp 333

prefixlogical table name 199name 354

prerequisite 396application 136for metadata storage applications 354

preview SQL 146primary key 50, 52, 108

column 108, 197column type 390define 197for every subclass 267foreign key 270inheritance 267multiple 259subclass table 270table 144

principle of uncertainty 39printable

reference string 161process

processes with transactions 325processor

SQL 281programming 5project name 41, 354prompter

for error 99unsaved changes 190

435

conform 140rule 140

physical naming support 142picture

load from file 345object 341

policyisolation of transaction 325merge 13

pool for query 279, 399practice

convenience methods 161

proof of concept 22property

(a) attribute 203(r) association (relation) 203attribute 52map editor 229map for subclass 263

property map(a) for attribute 33(r) association (relationship) 33editor 10, 64

property map editor

Page 462: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

for associations 33for attributes 33

proposal 22prove of concept 19public interface

define 337editor 164, 247, 337

Qqualifier, high-level 139, 145, 262query

custom 277entry point home 279generate static query 342helper class 281pool 279, 399selective 277static 342string 279

query pool 279change SQL 334service class 279

query string 279

RRAD 19rapid application development 19read

and copy 326CRUD 115, 214image 337

read-only 164attribute 161shared transaction 11

real-world application 14, 332record object modification 11

printable string 161string 164, 170supplies printable string 161

refreshbrowser 17load 17object 11

re-generatemodel 14model code 137

relation 4relational

attribute 134database 4, 8, 15, 19, 257service object 281view 7world 257

relationship 9bidirectional 156business object 5clear cache 35column 144define 54editor 28fix through new inheritance 396fix through override 394foreign key 14, 28forward 137, 231, 393framework 14inheritance 257many-to-many 241navigate path 14non-required 393one-to-many 131, 136one-to-one 137specify 14subclass 396

436 Using VisualAge Smalltalk ObjectExtender

recursion to sort changes 391recursive

remove recursively 305redundancies in tables 20reference 161

association 164attribute 170circular 147derive 161display 170, 214form 178printable 161

relationship, define 271release

all transactions 35model 60

removeobject 305recursively 305

remove... method 136repeatable-read

default 326isolation policy 325

repeatableRead transaction status 39

Page 463: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

repositorydevelopment 17metadata 16, 17

requiredadjustments of generated associations 203association 131association to self 391attribute value 203not default 203NOT NULL 145self-association 148

requirement 19case study 378

reset ObjectExtender 35reset, general ObjectExtender 61resolution

collision 333implementation on collisions 332

resourcelock 11sort 268trade-off vs. performance 270

responsibility for consistency 389result

collect from query 279generate 19large set 278

retrievedata 5row set 26

reusable form 170drag-drop support 171single reference 171

reusecollect result method 280model 227schema 227, 278

role 7, 244association 4, 131edit name 203name 203, 208

rollback 13, 39, 120root

class 398default persistence class option 55of inheritance tree 262of the model hierarchy 262root/leaf inheritance table map 272table 398

rowclass indicator 258delete from table 268discriminator 258heavy 26insert into table 268large set 26subclass indicator 258update in table 268

rulebusiness 14physical name 140

runtime 6, 15metadata 354set locking strategy 325

Ssample 3

database 105, 195, 231scenario 41test 246

sample objects setup 146save 16

map 69, 145, 230

437

reverse-engineer 8revert

map 17metadata 17model 17schema 17

reviewmap 64model 203model code 136schema 139, 197services classes 210

metadata 16model 50, 60schema 64, 107

save-yes/no/cancel 400scenario

development 3employee and department 41library 41, 42sample 41

schema 6, 8, 15adjust 197browser 8, 15, 22, 27, 61, 106, 109, 146, 198,

Page 464: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

344capture 20collision management 11create 8database 32deferred write 11define 244, 260, 270, 341export to database 146foreign key relationship 197generate 8, 19, 57, 61, 137, 138, 139, 260, 302import 20, 106, 196load 16load available 139map 227map to model 227name 106, 203, 300reuse 227, 278revert 17review 139, 197save 64, 107textual summary 64

scope of transaction 325scratch

develop from scratch 19scratch edition 231script 361

application 15generate 15generate default scripts 338object setup 148test 211, 309, 361verify local image data store 58VisualAge editor 37

selectclass for generation 56table 196

selection list 115

generate 137, 146, 304generate classes 210, 231generate classes options 231generation options 69inheritance 264, 273inspect classes 210layer 6name 300review classes 210

services classes 32generate 20, 69, 111, 146generation option 146name 129

session debug 35set

foreign key 136key 136

set selector 164set, large set of large rows 26setter 136

generated 39setup

sample objects 146script for objects 148

shared transaction 11, 83, 116global 11parent transaction 12read-only 11

sibling transactions 325side of foreign key relationship 207single reference

drag-drop support 171form 178reusable form 171

single table inheritance 258single table inheritance map 262

appropriate 259

438 Using VisualAge Smalltalk ObjectExtender

selective generation 54selective query 277self-association, required 148self-referencing, map entry 207sequence of generation 137service

class 279object collects the query result 279relational service object 281

services 6application name 112class 58, 210

drawback 258for all subclasses 263

single-window GUI 161Smalltalk 3

BLOBs 342sort

resource 268source data 106specify relationship 14speed

access 270to access database with inheritance 259

Page 465: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

spider web 178SQL 39, 146, 278

DDL 146dynamic 342error 100error -530, constraint violation with foreign key 399error for collision detection 333execution order 276, 399foreign key 399generate 146key for query string 281overqualified 332precompile 342preview 146processor 281queries for inheritance 259static 342string 281update 332use of CURRENT TIMESTAMP 334

SQL query string 279standard

debugger 77inspector 77

start ObjectExtender and tools 23state pattern 257state pattern design 44, 257, 387state-of-the art 19static

generate query 342query 342SQL 342

statistics of transactions 87, 123status

browser 35, 75, 87, 113, 123tool 16

storage name 110strategy

change dynamically 325for locking 325

stringconvert to image 337printable string for reference 161query 279reference 164, 170SQL 281

subclassall subclasses in one table 258discriminator 258inheritance 257naming 29object ID 259primary key 267property map 263relationship 396separate table 269, 398single table inheritance map for all subclasses 263table 270

subsetof all instances 278of information of an object 341

subtransaction 12level 12user interface 12

suffixfor names 354

summarymodel 109of your first samples 237top-down 102transactions 336

superclass

439

status browsermonitor 75view menu 35

storage 5, 6class 37metadata 16, 354

storage application namemodel 48

storage classcomment 37metadata 17name for model 48

change 354editor 260inheritance 260

supporthasModifications 400physical naming 142

survival 389switch transaction 13synchronize transaction 11syntax for host-variable 279system diagram

case study 385

Page 466: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

system overview of the library management sys-tem 42

System Transcript 303system transcript 36, 96, 98, 114, 146, 267, 361

tool 23systemwide sharedTransaction 87

Ttable 7, 28

column 9containing all subclasses 258create 146create map 228database 5, 8, 9, 146editor 62, 108, 197foreign key 139, 144foreign key relation ship 389large 278leaf 398map 64, 229map inheritance tree 260multiple for attributes 269name 139, 140prefix of logical name 199primary key 144redundancies 20root 398select 196separate for each subclass 269, 398single table inheritance mapping 258space waste 258subclass 270with complex dependencies 20

table and column name lengths 140table map with root/leaf inheritance 272tasks at development time 14

of model 24schema 64

timedevelopment 6runtime 6

timestamp 65, 333attribute 334of database for collision detection 334predicate 333

tool 3browser 6menu 23ObjectExtender 23overview 23start 23status 16system transcript 23

top-down 19combined with bottom-up 22conclusion 102employee 47path 47, 127, 227summary 102

top-level transaction 12, 13, 83parent transaction 12passed 328

trace 36, 280basic 37, 274detail 114detailed 274level 274message 56parameter definition 36

trade-off performance vs. resource 270transacted

business object 328contents of a variable 328

440 Using VisualAge Smalltalk ObjectExtender

test 309headless 113, 146, 211, 246, 264, 273, 282monitor headless 75navigation case 156sample 246script 211, 309, 361with GUI 122with user interface 96

textual summarydocumentation 22map 208model 52, 109

home 116object 328variable 13, 328variable contents 328

transaction 5, 11, 15, 325, 332active 11attribute of variable 328basic parts 83businessTransaction 87, 95, 119, 296changed objects 325characteristics 336child 12, 325, 328

Page 467: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

child transactions 287collision 11commit 268concurrent 325conflict 11context 38, 116current 13divide (if large) 12enhancedBusinessTransaction 87enhancement 400error 100failure 332form to display name 405framework 15, 83global 11ID 405in different processes 325in view 83initialize 328isolation 312lazy initialize in businessTransaction 96level 12level in nesting 13name 405nested 12, 254, 283, 317, 325, 330on different machines 325outside 325parent 12release all 35save GUI 190scope 325shared 11, 83, 116siblings 325statistics 87, 123status repeatableRead 39summary 336switch 13

access performance 341database access 19

typechange column type 389column 62, 139, 143, 229compatible 229converter 30details 30key column 144user-defined 337

types 337

UUML 3, 7

IBM VisualAge UML Designer (modeling tool) 19

uncertainty principle 39uncommitted changes 325unfinished association 389unintrusive inspector 40unit of work, consistency 5unrepeatable-read

isolation policy 325, 335unsaved

changes 190, 400changes prompter 190

update 5, 12CRUD 115, 214navigable 268row in table 268SQL 332

update counter 65updateSqlString

with CURRENT TIMESTAMP 334use case

case study 381, 382

441

synchronize 11systemwide shared 87top-level 12, 83top-level commit 326tree 286tree re-creation 286variable 13

transientgeneration option 69object 13

tree of transactions 286tune

use case diagramcase study 385

use cases in library 42user

defined types 337helper for queries 281interface 5

user code insertions 14user interface

consideration 12for test 96subtransaction 12

Page 468: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

user prompter 99utility

list connections 405

Vvalidation 14

error 305validation error 97validation error in metadata 207, 229value

appropriate for discriminator 263attribute 38attribute value not required 203discriminator 263

VapModelBrowserControledit association 389

VapSchemaColumnEditorModelvalid foreign key 389

variabletransacted 13, 328transaction attribute 328

verify with scripts 58version

business object 39class 16model 60object 13persistent object 13version 16

viewcreate with BLOB 345create with lite collection 342data store 15detail 122drag-drop support 170list 122

wasting table space 258WHERE clause 278work

cooperative 22service object 279

workspace 361world

object-oriented 257relational 257

write discriminator to data store 263

YY2K 265, 266

Zzap 389

442 Using VisualAge Smalltalk ObjectExtender

object-oriented 7relational 7with businessTransaction part 90with transaction 83

view menu of status browser 35visibility of changes anywhere else 326VisualAge 3

organizer 17Smalltalk, ObjectExtender xxi

Wwarning about inconsistent keys 390

Page 469: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

© Copyright IBM Corp. 1999 443

ITSO Redbook Evaluation

Using VisualAge Smalltalk ObjectExtender SG24-5258-00

Your feedback is very important to help us maintain the quality of ITSO redbooks. Please complete this questionnaire and return it using one of the following methods:

• Use the online evaluation form found at http://www.redbooks.ibm.com • Fax this form to: USA International Access Code + 1 914 432 8264 • Send your comments in an Internet note to [email protected]

Which of the following best describes you?_ Customer _ Business Partner _ Solution Developer _ IBM employee_ None of the above

Please rate your overall satisfaction with this book using the scale:(1 = very good, 2 = good, 3 = average, 4 = poor, 5 = very poor)

Overall Satisfaction __________

Please answer the following questions:

Was this redbook published in time for your needs? Yes___ No___

If no, please explain:

What other redbooks would you like to see published?

Comments/Suggestions: (THANK YOU FOR YOUR FEEDBACK!)

Page 470: Using VisualAge Smalltalk ObjectExtender · Using VisualAge Smalltalk ObjectExtender February 1999 SG24-5258-00 International Technical Support Organization

Printed in the U.S.A.SG24-5258-00

Using V

isualAge Sm

alltalk ObjectE

xtender SG

24-5258-00