Kicking EJB Development into High Gear with JBuilder

By: Patrick McMichael

Abstract: This session helps you kick your EJB development into high gear using JBuilder. Learn how to leverage the feature-rich user interface of JBuilder to visually develop and manage your EJBs. Topics include time-saving features such as: the EJB Designer (Visual EJB development, Entity Beans, Painless CMR, and the DTO/Session Facade wizard); the DD Editor -- Deployment Descriptor management for the rest of us; EJB test client wizards; and, running the container right inside JBuilder (deployment, debugging, and performance profiling). Examples leverage JBuilder and Borland Enterprise Server.

Patrick McMichael is a consultant with Pillar Technology Group, LLC, where he specializes in Enterprise Java development. Currently, he is serving one of the nation's largest wholesale food distributors as an application architect. His recent project work has been focused on the analysis, design, implementation, and performance tuning of J2EE-implemented enterprise subsystems such as item maintenance and cost management. Additionally, Patrick provides J2EE, UML, and JBuilder IDE mentoring/training to this client. Prior to his time with Pillar, Patrick worked for two years as a consultant for EDS, during which time he had the opportunity to do Java development for General Motor's BuyPower Web site. Patrick has a Masters in Computer Science from Grand Valley State University, where he specialized in OOAD and distributed computing. Last, but not least, Patrick has a lovely wife of six years, as well as a delightful daughter -- the two ladies of his life.

patmcmichael@comcast.net

Patrick W

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Patrick W. McMichael, Consultant

Pillar Technology Group, LLC.

 

Kicking EJB Development into High Gear with JBuilder

 

 


TABLE OF CONTENTS

TABLE OF CONTENTS.................................................................................................................................................. 2

TABLE OF FIGURES....................................................................................................................................................... 3

I. Introduction......................................................................................................................................................... 4

Background........................................................................................................................................................... 4

Purpose and Scope.............................................................................................................................................. 4

Cool Mixins............................................................................................................................................................. 5

II. The EJB Designer  EJBs gone RAD!........................................................................................................... 5

Getting the Cool Mixins Schema into an EJB Module................................................................... 5

Setting Up Some CMP Entity Beans.......................................................................................................... 10

Establishing Container Managed Relationships........................................................................ 12

DTO/Fagade Wizard......................................................................................................................................... 15

III. The DD Editor -- Deployment Descriptor Management for the Rest of Us............ 18

IV. Deploying and Running Your EJBs...................................................................................................... 20

Starting up Borland Enterprise Server and Deploying the Application...................... 20

Testing the Session Fagade......................................................................................................................... 22

Debugging EJBs with JBuilder..................................................................................................................... 24

Profiling EJBs with JBuilder....................................................................................................................... 25

V. Conclusion......................................................................................................................................................... 28

About the Author................................................................................................................................................ 30

 


TABLE OF FIGURES

Figure 1 Cool Mixins Database Tables...................................................................................................................... 5

Figure 2 New EJB Module from Object Gallery........................................................................................................ 6

Figure 3 Server Selection for EJB Module................................................................................................................. 6

Figure 4 Basic EJB Module Attributes....................................................................................................................... 7

Figure 5 Initial Workspace After EJB Module Creation......................................................................................... 8

Figure 6 Importing a Schema from the Database..................................................................................................... 9

Figure 7 CMP 2.0 Entity Bean Properties............................................................................................................... 10

Figure 8 Class Definitons for an EJB........................................................................................................................ 11

Figure 9 Modifying a field in a CMP 2.0 Entity Bean........................................................................................... 11

Figure 10 Relationship Properties............................................................................................................................ 12

Figure 11 Ice Cream to Creations CMR................................................................................................................... 13

Figure 12 Edit Table Reference................................................................................................................................. 13

Figure 13 Add Cross Table......................................................................................................................................... 14

Figure 14 CMR Result View....................................................................................................................................... 15

Figure 15 Excluding lastUpdateTimestamp from DTOs........................................................................................ 16

Figure 16 - Resulting Workspace after DTO/Facade Wizard............................................................................... 17

Figure 17 Deployment Descriptors........................................................................................................................... 18

Figure 18 EJB Local Reference -- Structure Pane.................................................................................................. 19

Figure 19 EJB Local Reference -- Standard............................................................................................................ 19

Figure 20 EJB Local Reference -- XML.................................................................................................................... 20

Figure 21 Successful startup of the BES Management Agent.............................................................................. 20

Figure 22 Trailing Output of Successful BES launch and CMExamples Deploy............................................. 20

Figure 23 BES 6.0 Console......................................................................................................................................... 21

Figure 24 EJB Test Client in Object Gallery........................................................................................................... 22

Figure 25 EJB Test Client Details............................................................................................................................. 23

Figure 26 JUnit Test Output....................................................................................................................................... 24

Figure 27 New Server Run Configuration............................................................................................................... 25

Figure 28 Optimize Config Settings for BES........................................................................................................... 26

Figure 29 Starting the CPU Profiler......................................................................................................................... 27

Figure 30 Example OptimizeIt Results...................................................................................................................... 27

 


I. Introduction

Background

Enterprise Java Beans, or EJBs, are a vital component of the overall J2EE platform. These objects, living and breathing within the EJB Container, provide the backbone business logic behind many of todays enterprise systems. Moreover, because of their contract with the EJB Container, they benefit from the many services a container provides, including things like transaction management, security policies, location transparency, and more.

The one criticism frequently laid against EJBs, however, is the complexity surrounding them. The EJB 2.1 specification is over 600 pages long! While the container manages many details for the developer, care still has to be taken to build all of the appropriate interfaces, deployment descriptors, etc. in a manner which is both syntactically and contractually valid. Not only that, but certain things cannot be caught at javac compile timetheyre only caught by a vendor-specific EJB compiler. Still other potential violations, such as inadvertent reentrance, are not caught until runtime, when redesign is costly. Interestingly, the EJB 3.0 specification is moving towards answering many of these long standing criticisms (http://www.theserverside.com/news/thread.tss?thread_id=25779). Unfortunately, things dont always move through the JCP very quickly, so this reduction in complexity may be some ways off yet.

So, the question is, how do we harness the power of EJBs today, but in a way that shields developers from much of their complexity? This is where the right IDE justifies its cost quickly in productivity gains and with early lifecycle prevention of errors.

Purpose and Scope

 

In this paper, we will see by example some of the incredible features JBuilder brings to the table when it comes to EJB development. Well take a look at the visual EJB Designer and how it radically simplifies the EJB development process. Well see how the DD editor makes deployment descriptor management attainable for those of us who have better things to do than to memorize DTDs all day long. Well also see how JBuilder can be used to deploy EJBs to an application server, in embedded mode, for easy testing, debugging, and optimization.

This paper is focused on showing how to kick your EJB development into high gear with the powerful JBuilder IDE. In the course of this discussion, there will be numerous mentions of various aspects of EJB and related technologies. It is beyond the scope of this paper to provide any background training on such technologies, so the reader is encouraged to pursue these matters independently. An Additional Resources section of this paper provides some starting points for such study.

Cool Mixins

To achieve this purpose of providing exposure to leveraging JBuilder for EJB development, we need an example problem domain. Discussion and examples surrounding will use the fictional Cool Mixins ice cream store as a common point of reference.

In a day in age where national chains and cable television extol the virtues of the fearless Do-It-Yourselfer, some of us are left with reason to despair. Grandiose visions of the outcome of the latest round-the-house weekend endeavor often come plummeting back to reality upon project completion. THAT wasnt what I thought this would look like! For those like myself that can relate to such sentiments, take heart!

This paper will focus on a Do-It-Yourself project that anyone can handle  inventing your own ice cream delights. At the Cool Mixins store, customers can choose a creation invented by the store or another customer, or they can put on their inventor hats and mix up their own unique concoctions. Each ice cream creation is tied to a particular inventor, has an ice cream flavor as its base, and then an assortment of mix-in ingredients (fruit, candy, toppings, etc.).

 

II. The EJB Designer  EJBs gone RAD!

Getting the Cool Mixins Schema into an EJB Module

 

The figure below shows the tables used in the initial Cool Mixins schema. Certainly the full blown store software would entail many more tables, but this will get us on our way.

Figure 1 Cool Mixins Database Tables

We want to bring this schema in to our project, so that we can rapidly establish EJB services surrounding this core data. Before we can do this, however, we need to add an EJB module to our project:

 

1)      Select File | New to bring up the JBuilder Object Gallery.

2)      Select EJB under the Enterprise section, as seen in the figure below.

Figure 2 New EJB Module from Object Gallery

 

3)      Click OK. This will prompt you for server selection. Well use Borland Enterprise Server 6.0 as the single server supporting all services (EJB, Web Container, etc.) for our project, as shown in Figure 3. Click OK.

 

Figure 3 Server Selection for EJB Module

4)      Now that a server has been selected for the module, youll be prompted to specify details for the module. Accept the default option of creating an empty module, and click Next.

5)      Enter CMExamples as the logical module name as well as the directory name. This directory will be put under your project root and will be a placeholder for EJB module artifacts, such as the generated deployment descriptors. Leave the other options defaulted as shown below. Click Finish.

 

Figure 4 Basic EJB Module Attributes

 


6)      We now have an EJB module, ready to start our real work with. Your IDE workspace should now resemble the Figure 5 below. Notice the CMExamples module in the Project Pane, which is opened as the Visual EJB Designer in the main pane.

 

Figure 5 Initial Workspace After EJB Module Creation

 


7)      Now we can import our schema. (Note: This step assumes that you have copied the coolmixins.jds JDataStore file onto your local file system from the provided sample code.) Right click on DataSources in the Structure pane seen above. Select Import Schema from Database. In the resulting dialog, whether by manual entry or by Choose Existing Connection (e.g. if youve browsed the new datastore with Database Pilot already), make sure the following values are entered. Pay special attention to the JNDI name.

 

Figure 6 Importing a Schema from the Database

 

8)      Click OK. This should result in a Structure Pane populated as in Figure 1 above.

 

 


Setting Up Some CMP Entity Beans

 

Lets say weve decided to use CMP Entity Beans as our persistence mechanism for Cool Mixins core data entities. Having the schema imported into our project makes this work a snap with JBuilders EJB Designer.

 

1)      Right click on the CREATION table in the Structure panes CoolMixinsDS tree.

2)      Select Create CMP 2.0 Entity Bean. This will add a new bean to the EJB Designer view.

3)      Lets take care of the high level settings for our new Entity Bean first. This will bring up a dialog like the one in Figure 7. This dialog specifies the logical bean name, Creation, which were also using as the EJB 2.0 abstract schema name. Were only providing local interfaces, which is the norm for entity beans since theyre typically fronted by session beans. Our primary key, id, is a simple Integer object, so theres no need for a CreationPK wrapper class here.

 

Figure 7 CMP 2.0 Entity Bean Properties


4)      Next, select Classes and packages in this dialog. Populate the dialog as shown in Figure 8. Click OK. Notice how the local home and business interfaces, plus the abstract CMP 2.0 Entity Bean class are all created for you under the specified package. Feel free to explore these by clicking on them from the Project pane.

 

Figure 8 Class Definitons for an EJB

 

We went with the default field types for this bean, but any field can be visually altered with the EJB designer by left clicking the field as seen in Figure 9 below.

 

Figure 9 Modifying a field in a CMP 2.0 Entity Bean


5)      Repeat these steps for the ICE_CREAM, INVENTOR, AND MIXIN tables. Do not do anything with the associative CREATION_MIXIN table at this time.

 

 

Establishing Container Managed Relationships

 

We indicated in our introduction that creations have some key relationships. Specifically, a creation has one base ice cream flavor, though the same ice cream flavor can be used in many creations. A similar many-to-one relationship exists between creations and inventors. In the case of mix-in ingredients, a single creation may use multiple of these, and these mixins can be used in many creations. These, therefore, are part of a many-to-many relationship. Lets use JBuilder to quickly establish these relationships.

 

1)      Right click the Creation Entity Bean and choose to Add Relationship. Use the mouse to connect the red arrow that appears over to the IceCream Entity Bean. Youll see that an iceCream CMR field is added to Creation. Left click this field to bring up the relationship properties dialog as seen in Figure 10.

 

Figure 10 Relationship Properties


2)      Set the multiplicity and navigability as shown. Making the relationship bidirectional adds a creation field to IceCream. Since ice creams can be used in multiple creations, update the field name to creations (plural) as seen in Figure 11.

Figure 11 Ice Cream to Creations CMR

 

 

 

3)      We now need to map this relationship to the underlying table. Click on Edit Table Reference to do this, and establish the relationship depicted in Figure 12.

Figure 12 Edit Table Reference

 

 

4)      Following the pattern set in steps 1 through 3, repeat this for the relationship between creations and inventors.

5)      Do this one more time for the relationship between creations and mixins, BUT this time, be sure to specify many-to-many. When you edit the table references, be sure to select Add Cross Table. Thats rightwe finally do something with the CREATION_MIXIN table. Map this many-to-many relationship as shown in Figure 13.

Figure 13 Add Cross Table

 


6)      The final result you see in the EJB Designer should look like the Figure 14.

 

Figure 14 CMR Result View

 

 

 

DTO/Fagade Wizard

 

Now that we have these CMP Entity Beans primed and ready, its time to front them with one or more Session Beans, as per the Session Fagade pattern (http://java.sun.com/blueprints/corej2eepatterns/Patterns/SessionFacade.html). Remember that we exposed our entities with local interfaces only. We want to provide a remotely accessible Session Bean that can use these entities, but expose their data via DTOs (data transfer objects). Here again, JBuilder takes a tedious task and makes it near effortless!

 

1)      Right click on the Creation entity and choose Launch DTO/Fagade Wizard. Were going to keep it simple and creation just the fagade, not the business delegate for now. Specify this and click Next to proceed to step 2 of the wizard.

2)      The wizard realizes that we have established relationships to the Creation entity, so it prompts us to specify which relationship beans we also want DTOs created for. Allow the wizard create DTOs for All of these, then click Next.

3)      Next, you must specify a package for each DTO that will be created. We will use the package com.coolmixins.dto for these classes. Be sure to specify this for each DTO that will be created before clicking Next to proceed to step 4 of the wizard.

4)      Step 4 of the wizard allows fields implied by the entity beans to be excluded. We use timestamps for auditing in the database tier, but dont necessarily need these in our client-facing DTOs. For each DTO to be created, exclude this field as shown in Figure 15. Click Next.

 

Figure 15 Excluding lastUpdateTimestamp from DTOs

 

5)      Step 5 of the wizard allows a package to be specified for each DtoAssembler class that will be generated. This class gets used by the session fagade to convert from Entity Bean to the client-exposed DTO. Specify the com.coolmixins.dtoAssembler package for each one and click Next.

6)      This step is where you specify the bean, home, and remote names for the Sesssion Fagade to be generated, as well as the package. Go with the default names for the class/interfaces, but change the package for each one to com.coolmixins.ejb and click Next to go to the last step.

7)      This step allows the name and package of the ServiceLocator object for the Session Fagade pattern to be specified. Leave the default name, but change the package name to com.coolmixins.util. Click Finish.


A number of classes will have been generated by this point. Bear in mind that you have yet to write a single line of code. JBuilder is generating all of this patterns-based, boilerplate code on your behalf! At this point your workspace should appear as depicted in Figure 16 below. Feel free to browse through the DTO/Fagade classes that have been generated by clicking on any of them in the Project pane. Additionally, you should be able to rebuild the entire project successfully.

 

Figure 16 - Resulting Workspace after DTO/Facade Wizard

 

 

 

 


III. The DD Editor -- Deployment Descriptor Management for the
Rest of Us

 

We mentioned in the introduction that one of the points of complexity with EJB development is the management of deployment descriptors, or DDs. In and of themselves, these are simply XML files. There is one standard, per-the-spec DD, ejb-jar.xml, as well as one vendor/container specific DD -- ejb-borland.xml in our case. While JBuilder allows you to manage these visually with its DD Editor, you can also browse and hand-edit these. Figure 17 shows these under the EJB module you created earlier. Feel free to pop these xml files open and snoop around.

Figure 17 Deployment Descriptors

 

Lets see this from a visual perspective. Either click on the EJB ModuleDD Editor tab in the EJB Designer, or right click on an EJB in the designer and choose Open DD Editor. Looking at the next three figures, notice how we can browse to an deployment descriptor element for any EJB via the Structure pane. Using Figure 18 as a guide, browse to the EJB local reference added by the wizard in the previous section. Specifically, this wizard established a JNDI ENC reference to the Creation Entity Bean for the CreateSessionFacade EJB. Double click on that entry, which brings up a tabbed DD view such as the one in Figure 19. Because this is a local interface, we can use the DDs link syntax. Because of this, no vendor-specific mapping is needed. Otherwise, we would have mapped the JNDI ENC reference to the actual JNDI name on the BES tab. Lastly, Figure 20 shows the physical XML that was generated.

You are not limited to entries made by wizards. The DD editor can be used to manage everything from DataSources, JMS resources and destinations, security policies, method transaction attributes, etc. Again, it is not the purpose of this paper to give the technical details on each of these, but rather to point out how the JBuilder IDE makes EJB development and management much simpler with its visual tools.

 


Figure 18 EJB Local Reference -- Structure Pane

 

Figure 19 EJB Local Reference -- Standard

 

 

Figure 20 EJB Local Reference -- XML

<ejb-local-ref>

<ejb-ref-name>ejb/creation</ejb-ref-name>

<ejb-ref-type>Entity</ejb-ref-type>

<local-home>com.coolmixins.ejb.entities.CreationHome</local-home>

<local>com.coolmixins.ejb.entities.Creation</local>

<ejb-link>Creation</ejb-link>

</ejb-local-ref>

 

IV. Deploying and Running Your EJBs

 

Starting up Borland Enterprise Server and Deploying the Application

 

Weve created a substantial amount of code by now. Lets go ahead and get it deployed for some preliminary testing. Heres the steps:

 

1)      From the Enterprise menu, launch the BES 6.0 Management Agent. If all goes well, you should see a message like the following:

Figure 21 Successful startup of the BES Management Agent

Local Hub patrick

Management Port: 42424

Startup completed.

 

2)      After a fresh rebuild of the whole project, right click on the CMExamples EJB Module in the Project pane and select Run using defaults. If everything went well, you should see trailing output in the message pane like that in Figure 22.

 

Figure 22 Trailing Output of Successful BES launch and CMExamples Deploy

.

.

.

2004-05-23 20:32:07,528 INFO - Loaded J2EE module CMExamples.jar.

2004-05-23 20:32:07,528 INFO - Loaded all J2EE modules.

2004-05-23 20:32:07,528 INFO - Partition [jbpartition] started

2004-05-23 20:32:12,245 INFO - EJB Container Statistics

========================

Time Sun May 23 20:32:12 PDT 2004

Memory (used) 6483 Kb (max 6483 Kb)

Memory (total) 65152 Kb (max 65152 Kb)

Memory (free) 90.0%

------------------------

Home (remote) CreationSessionFacade

Total in memory 0

Total in use 0

------------------------

Home (local) Creation

Total in memory 0

Total in use 0

------------------------

Home (local) IceCream

Total in memory 0

Total in use 0

------------------------

Home (local) Inventor

Total in memory 0

Total in use 0

------------------------

Home (local) Mixin

Total in memory 0

Total in use 0

========================

 

3)      If you choose View | Panes| BES 6.0 Console, you can also launch the BES 6.0 management console right inside JBuilder. This results in a view something like that in Figure 23.

 

Figure 23 BES 6.0 Console

 

Note that all of this is being handled right inside the JBuilder IDE! Theres no need to jump back and forth between the IDE and scripts/command line utilities. JBuilder puts all this power right at your fingertips!

 

Testing the Session Fagade

 

So, weve generated all of this code, its successfully been built and deployed  now what? Its time to see if what weve put out there in the application server actually does anything.

 

1)      Select EJB Test Client from the Object Gallery (File | New).

 

Figure 24 EJB Test Client in Object Gallery

 

2)      In the wizard that comes up, select JUnit Test as the type of test client well create and click Next.


3)      In step two of the wizard, be sure you specify settings matching the figure below, then click Next.

Figure 25 EJB Test Client Details

 

4)      In the final step of the wizard, Step 3, be sure to allow the wizard to generate a run configuration for you. Click Finish.

5)      A real-world JUnit test would likely be an ordered flow of actions to create, read, update, read to verify update, and remove. This would ensure repeatability of the test. For our purposes, well avoid the cross-object dependencies and start with a simple finder test. (Note: You should have already copied the coolmixins.jds JDataStore file onto your local file system from the provided sample code.) This file has some pre-seeded data we will use in this test.) Modify the generated TestCreationSessionFacadeTest1 class as follows:

a.       Remove the @todo in the setup method and replace it with a call to create(). This will ensure that the fagade is obtained from the home interface and ready for use by our test method.

b.      Comment out all testXXX methods except for testCreationFindByPrimaryKey. In that method, replace the line containing Integer id = null; with Integer id = new Integer(1);

c.       Add one more logging output line: log("Creation #1: " + aCreation);

d.      Rebuild this class.

6)      With the appserver still running, execute the JUnit test with the Run Configuration established at the end of the test client generation wizard.

7)      You should see JUnit output as shown in the figure below. If youve got all green, CONGRATULATIONS!

 

Figure 26 JUnit Test Output

 

 

Debugging EJBs with JBuilder

 

Debugging EJBs right inside JBuilder is equally simple to do. Follow the steps below to try this out.

1)      Close the JUnit test tab in the Messages pane.

2)      Stop (red square) and close the BES 6.0 Run tab in the Messages pane. You can leave the Management Agent running still.

3)      Place a breakpoint in the assembleCreationDto method where return CreationDtoAssembler.createDto(creation)gets called.

4)      Right click the CMExamples EJB module, but this time select Debug using defaults. Wait until the server successfully starts up, watching the log output as before.

5)      Once it is fully up and running in debug mode, reexecute your JUnit test with its run configuration. When your breakpoint gets hit, press F7 to step into the DTO Assembler classes method. From there, feel free to step in, over, or out of code, to add watches, etc. Anything you can do with the JBuilder debugger elsewhere is also available to you for debugging your EJBs.

6)      Once youve finished experimenting, go ahead and hit F9 to run. If there are no more breakpoints, your test should complete in the green just as before.

 


Profiling EJBs with JBuilder

 

Lets demonstrate one other thing with our Cool Mixins application. Proceed as follows.

 

1)      Stop and close the BES 6.0 Run tab as in the debug example.

2)      Go to Run | Configurations and choose New. Select Server as the run type. Modify the Run configuration to look like this:

Figure 27 New Server Run Configuration

 


3)      Go over to the Optimize node in the tree and configure it for CPU profiling only, pending a manual start of the profiler (see Figure 28). Click OK to finish the Launch BES configuration and OK again to close out the initial dialog.

Figure 28 Optimize Config Settings for BES

 

4)      Execute the Launch BES run configuration with the OptimizeIt run toolbar button (the run arrow with a clock/timer icon). Wait until the server is up and running in profiling mode.


5)      Switch to the profiler sub tab and start the profiler as seen in the figure below.

Figure 29 Starting the CPU Profiler

 

6)      Rerun the JUnit test again until youre in the green. Once it has completed, press the icon to stop the CPU profiler in the OptimizeIt window. You should now be able to see profiling results from your work in OptimizeIt just as you would outside the EJB container. An example (your results may vary) is provided in Figure 30.

Figure 30 Example OptimizeIt Results

 

V. Conclusion

Through the course of this tutorial, we have seen in numerous ways how simple JBuilder can make EJB development. Much of the commonplace, tedious, boilerplate type of code can be generated for you in a visual, almost RAD-like manner. Deployment descriptor XML data can be managed visually as well, sometimes through wizards, other times through the DD Editor.

JBuilder not only makes the writing and management of EJBs a cinch, it also provides full debugging and profiling capabilities right inside the IDE! The ability to do everything from one central location is very powerful.

Hopefully this tutorial has provided you with some insight as well as some inspiration of some of the ways you can use JBuilder in the real world to kick your EJB development into high gear!
Additional Resources

 

1.      J2EE 1.3 and 1.4 APIs:

http://java.sun.com/j2ee/sdk_1.3/techdocs/api/

http://java.sun.com/j2ee/1.4/docs/api/

 

2.      An in-depth EJB primer all developers should have:

Monson-Haefel, Richard. Enterprise JavaBeans. 3rd ed. Sebastopol: OReilly &

Associates, Inc., 2001.


About the Author

 

Patrick McMichael is a consultant with Pillar Technology Group, LLC, where he specializes in Enterprise Java development. Currently he is serving one of the nation's largest wholesale food distributors as an application architect, helping to design and implement a team selling support system.

 

Patrick has a Masters in Computer Science from Grand Valley State University, where he specialized in OOAD and distributed computing.

 

Last, but not least, Patrick has a lovely wife of six years, as well as a delightful daughter, the two ladies of his life.

 


  Latest Comments  View All Add New RSS ATOM

Move mouse over comment to see the full text

Server Response from: ETNASC02