WWDC2000 Session 403

Transcript

Kind: captions Language: en hello as he said I'm Mike goby I'm one of the trainer's here at Apple and although I usually train in front of crowds of people this is a first for me for a crowd this large so if I seem a little bit nervous well I'm not I'm just bluffing really well how many people here have ever used a of' web objects or any of these technologies before almost everybody how many people here never have okay hopefully the people who never have we'll give you a quick sketch to go into this but my basic assumption in this exercise is that you either have a basic idea of what's happening or if you don't you come and watch the previous demonstration so you'll have at least a few minutes old knowledge of what's happening I'll be talking about persistent object modeling with EO modeler which is a technology we use to connect from a database through the web application and out to the browser on the user interface so web objects is the new technology from Apple that lets you build dynamic websites and most of these websites are backed up by relational databases typically you'll have an e-commerce application that lets customers make purchases you need to know what products can be sold and that's all stored in a relational database and EOF allows the persistent access to that data within your object-oriented application in this presentation I'll talk about the basics of what is a OS it's Enterprise objects framework on what is woof the web objects framework and how these two technologies can work together to build your application I'll talk a bit about ile modeler the tools that you actually use to configure your application and tell it how to connect to the database I won't be talking in this too much detail about how databases work so I'll give a quick sketch of the basic technology of what a table is what a row is but it won't go to very much detail beyond that so what are the basic concepts we need to know well first we need to know the structure of a web application and the architecture of web objects and enterprise objects and how they fit together to make your location and finally I'll talk about some entity relational modeling concepts start off to the web application typically this is a three-tier model from the first side we have a browser in the middle we've got your web application and finally backing it all up we have a relational database when some users somewhere on the internet type the URL into the browser an HTTP request gets sent to your application your application will this end a sequel request off to the database to request the objects it needs to serve as the HTTP request the sequel database gives rows of data back to your application as simply raw data but because this is an object-oriented application those rows of data will get turned into objects that your application can use your application then takes those dynamically fetched objects and turns them into HTML to get sent back out to the browser and all this is something that we call the request response loop now web objects does more than just this it also keeps track of the unique editing context for every user so we already have one user who has fetched information from the database perhaps they've fats the record and are about to make a purchase so we've fetched the number of available records from the database but while they're making the decision some other user comes along and that other user will send a request to the application which will result in a sequel fetch and some data coming back to the web objects application and even if the same rows are retrieved that have already been shown to the other user EOF will create a completely different pool of objects that are stored in a separate editing context and that way the two users don't interact with each other till one of them actually tries to make a purchase or does something that will commit their changes to the database and finally those objects will turn into HTML they get sent out to the second user so the web objects framework represents the top half of this object-oriented application the web objects framework knows how to take these enterprise objects and turn them into HTML to be displayed on the web the enterprise objects framework that's the part I'll be talking about in this presentation knows how to talk to a database fetch in rows of data and then create objects that web objects can then use to produce HTML so we have a layered architecture at the very bottom you'll have third party database libraries the Oracle database libraries standard ODBC libraries whatever third-party libraries you need on top of those we have the adapter layer which knows how to connect to the database and just set raw data the database layer which knows all about the classes in your application and knows how to turn that raw data into an object for you to use the control layer which keeps track of what you've done to those objects so if you make changes you can eventually save those changes back into the database or maybe undo or redo the changes and then finally we have the web objects framework on the very top and the web objects framework knows how to take those objects and present them to the user in HTML and the database and adapter layer are what we'll be editing using yo modeler all of the changes that we make to describe how the database and the application will interact live inside something we call the model file and the model file just describes a straightforward one-to-one relationship this class goes to this table this column goes to this instance variable although it can be more complicated if you have a class that spans several databases and to edit the ill model file we'll use a tool cleverly enough named yo modeler and yo modeler knows how to configure the adapter to say which database you're connecting to it knows how to work with the schema edit the entities the attributes from the relationships and it can identify the various stored procedures and let you create fetch specifications to be used later when you actually run the application so the first step in ill modeler will be to configure the database adapter you'll choose configure adapter from the menu bar and then from the list of available adapters you'll choose which database you want to pick in this case we've chosen the Oracle database and once you go on from there you'll get a custom Oracle login panel - lets you configure which Oracle database to connect to what's the username you want to use is what the password is and when you say ok all of that gets put into the model file for later use by your application once you've connected to the database we have to work with the entities that is the tables in the database in the database the entity is simply a table and in the application it's a class not a particular object but entire class of objects in your object-oriented application in this case the studio table and the studio class to create an entity using yo modeler you'll choose new entity and using the inspector panel you'll specify what the direct what the name of the table is the name of the entity is in this case the director entity the name of the table and the name of the class in your application and if you want to keep your life simple you'll probably want to choose similar names like director and director although EO modeler doesn't actually care and in fact if you don't care about the class at all we have a special class you can use called the EO generic record which is essentially a glorified dictionary all it does is fetch data from the database and stores it as key value pairs in a dictionary so you can display the data but you can't put in any custom business logic if you wanted custom business logic would choose a class name such as director class or even just director ill Mahler also lets us set up the attributes in the database an attribute is the name of a column in this case the name column of the studio table in our object-oriented application it's an instance variable in the various objects so we have the studio has the Warner Brothers and twentieth century-fox and here we have two instance variables containing Warner Brothers and twentieth century-fox now most attributes are what we call simple attributes just simple strings integers floating point numbers a neo F automatically knows how to take that data from the database and convert it into the appropriate Java data types we also have more complicated data to get stored in the database as a blob and a blob is just a large chunk of data usually containing an image or a sound quicktime movie and they do get read out of the database into a special class called the NS data class and in your model file you specify which particular class like NS image or NS sound you want that data to turn into and which factory method will actually convert the data object into the particular class that you need and finally the third type of attribute will have our key attributes primary keys in database terminology are the column that uniquely identifies a row and a foreign key is a column that uniquely identifies the row in some other table now in your object-oriented application we don't actually have primary and foreign keys at all because we don't need them objects are intrinsically unique this computer monitor and this computer monitor are different because there are different places in the same way in your application two objects are in different locations in memory so we don't need a primary key to tell them apart they're already unique so if we want to edit the attributes in EO modeler first we'll select the particular entity that we want to work with like the director and once the director has been selected on the top we'll see a list of all of the attributes of that director the wrote lined in blue on the screen and if we bring up our inspector panel we'll see that this particular attribute is called the talent ID its database column it's talent ID it's a long type in the database and in our application it's stored as an integer relationships are a bit more complicated in the database a relationship is a joint operation between the primary key of one call one table in this case the studio ID of the studio table and a foreign key of a different table the studio D ID in the movie table now in the application when you actually instantiate your objects the relationship is represented as an instance variable that points off at other objects so here we have the movies variable which points to an array of movie objects now there's two kinds of relationships in the database that look very similar a to one relationship or it too many but in the application they look quite different in the application a relationship to one is simply a pointer a variable that points directly to another business object the movie points to its studio a to many relationship on the other hand points to an array of other objects so here we have the movie variable which refers to the array of alien and Star Wars we also have the choice between a one-way or a two-way relationship in the case of a two-way relationship the studio knows all about its movies and the movies all know about the studio that the rim but this does occupy more memory in your application and it also introduces the possibility of inconsistency where the movie may contain a studio but that studio doesn't have a back pointer to the movie so what you might choose to do to simplify your object model is take out the back pointers and only have a one-way relationship so now our studio knows about the movies but a given movie doesn't actually know what studio it came from an do model or the way you would do this is by only setting up one half of the relationship you can fear the two of them independently so to use eel modeler to edit our relationship once you've selected the entity we'll go down to the bottom half of the screen and we'll see a list of all of the relationships if we select your relationship in this case the movie and bring up our inspector panel we see that we can give it the name movie the entity is a movie so it's a relationship from the director table to the movie table and we're using the movie ID of the director and the movie ID of the movie table to actually resolve this relationship when we perform the fetch many-to-many relationships in the database require a third table this is a situation where a movie could have multiple talents who starred in the movie but at the same time a given talent I give an actor could have acted in several different movies in the database we need a third table that's called the join table and it simply has the primary keys of the appropriate movie and talent to form the relationship in the application we don't need that third class because we simply have the movie maintains an array of talent every piece of talent will maintain an array of movies and when you update the relationships Co modeler a neo F will automatically insert the appropriate rows into the acted in table to form that relationship happens quickly to set up this relationship and yo modeler you could create that entity create the relationships and put it all together by hand but that's fairly tedious so instead the engineers of Apple gave us a nice graphical user interface way to do it we'll simply select the two entities in this case the movie and the talent and from the property menu we'll choose join in many-to-many when we do that a third entity gets created the movie talent entity and all of the appropriate relationships are set up so that now we have the many-to-many relationship if we were to select one of the entities in this case the movie and choose the talents relationship and bring up the inspector panel we don't get the usual relationship inspector this inspector panel just tells us that this relationship talent is actually a combination of the movie talent relationship in movie and in the talent relationship in movie talent and we'll just use a dot notation to join them together we can also use ill modeler to set up relationships between more than one database this is especially useful and we have to connect to legacy systems where we didn't get to design the databases and we have one system from one company that was used one database environment and then perhaps a newer company that is just been acquired uses a totally different database system and your application needs to talk to both well a neo modeler the way we'll set this up is first we'll open up the model file for one of the databases in this case the video rentals and now we have another database of all of the movies ever made the movie stars database within the video rentals will simply select the entity that we want to create a relationship in and bring up the relationship inspector now there's a pop-up labeled model in this case it's set to video rentals a relationship back into the same database but all we have to do is select the pop-up list and change that to the other database the movie stars database and from there on we'll just wire things up in the usual way specify which entity in the movie stars database we want to use whether it's a to one or a to many relationship and specify the attributes that were used we'll do to create the join an hour runtime when you actually try to fetch a video-rental EOF will automatically perform a fetch across the databases perform the appropriate cross database join and retrieve all the information that you need if you update the relationships and then save your changes yo elf will automatically save the appropriate changes to each database to keep your relationships intact so that was part one the basics of how does a of' work what is yo modeler and what is the database anyway well the next thing to do is how to work specifically with the entities we have a particular studio or talent or director table in the database well what do we want to do with it we'll probably want to generate some sequel code if we haven't already inherited a database from our legacy you might want to browse the data see what's already there if there already is a database that exists who might want to just pull all that information into you modeler and Ivo modeler builder entities for us and finally to actually start writing our application we'll probably want to generate some Java classes to generate the sequel you simply select the particular entity in this case the talent and bring up the sequel generation panel and here we'll say that we want to drop the old table drop the old support for primary keys create a new table create the new primary key support and we can see all of the sequel code that will get executed and we can either execute it immediately or save it off into a temporary file so we can give it to a database administrator to execute on a remote server if the database already exists you might want to browse the data so in this case we could select the talent table talent entity bring up the data browser and see a list of all of the talent in the database we can also type in a particular qualifier last name begins with F and just see the talent whose last name begins with F and if we already have a database which nine times out of ten is the situation because we already have existing applications we're now trying to move into the internet we can just use the reverse engineering tools to specify which database we're using in this case open based Lite bring up the login panel to specify how to connect to that particular database and where it's located and then choose information help us guide us through the creation process yes we want to give primary keys to the entities yes we want to use custom enterprise objects so if there's a talent table we want yo modeler to automatically generate the talent class for us to use and then finally select all of the table from all the tables in the database which particular tables we want to use in the model file and the last thing we'll want to do once we've already imported our model and started to work with it for a while and in the meantime our database administrator over in that corner of the world is busy working with our database schema we need to bring these two worlds into sync again and we can use that by we can do that by bringing up the synchronized schema window and that window will list all of the new tables in the database or new entities in your model file any new attributes that were added or any attributes these properties were changed and when you click the synchronize button Ile modeler will automatically go and make the appropriate changes to your model file into the database once it's synchronized and our application is now in sync with the database we can generate some Java classes so we can start coding our application so again you'll just select these entity the talent say please generate some Java classes specify where to save them and if you do try to save them into a project then the panel or panel will appear asking you whether you want to add the files to the project as well as just putting them physically into the project directory and at that point those Java classes are now standard Java source code you can fire up project builder make any edits you need to make and then build and run your web objects application and the last tool that you'll modeler provides is a convenient diagram view to give you a graphical mute view of your schema and you can just inspect this view to see what your various entities are and how they're related or if you want you can actually do simple edit operations creating relationships breaking relationships or renaming various attributes directly in the diagram view so now we know some basic database concepts we know how to use yo modeler to do a little bit of custom configuration how do we generate the de sequel how do we generate the Java classes well the next step now that we have our application up and running is actually going to be to have runtime behavior how do we validate the data keep bad information from hitting the database how do we detect a conflict when two different users are both trying to edit the same record at the same time shared entities we can use for memory improvements and then we can use stored procedures ah excuse me and fetch specifications to also give our application better performance so there's different ways to validate the simplest validation is done right within yo modeler bring up the inspector panel for an attribute click on the second icon in the icon path and you can see the advanced inspector and in this inspector we can say this entity will not permit null values in the attribute for example a customer can't have no for a last name you can limit the string lanes we won't sell to anybody whose name contains more than 15 characters because we have an old database that just can't cope with it maybe we can make a relationships mandatory perhaps every customer has to have a sales representative or perhaps every movie has to have a director and we can also specify what happens when we do a deletion if I delete a studio should I also delete all the movies that studio created should I set them up as movies with no studio or should I in fact refuse to allow the studio to get deleted until I've first gone through manually and reassigned movies and this validation is fairly useful but often doesn't meet all of our needs maybe it's okay to have last names that are not null or no but what if we want to put any rules that say the last name can't contain any spaces that's more complicated than yo modeler can represent so to do that sort of validation in your java class you'll create a special validation method in this case validate for save throws an EO validation exception and before we try to save the changes to the database we'll check and if the person is too young but claims to have a driver's license we'll throw the exception saying we're not going to let that data into the database you can also write custom validation methods for every attribute so we could just say validate last name and that method will automatically get cold if the user tries to change somebody's last name in addition to validation on a single user basis making sure that a particular user doesn't try to let a young person drive a car we can also get a problem of conflict detection where perhaps over here in one application I've decided that this customer is in fact only 13 years old because I just called her up talked to her parents and found out that no she's not 26 after all meanwhile offi in another corner of the world some other user has called up the same customer record and has just tried to give the user a driver's license now each of those operations independently is correct but put together they'll form a conflict eel modeler an EOS supports two ways of dealing with those conflicts if we use pessimistic locking we're going to assume that there are problems and the way we make ourselves safe with that assumption is when AOL fetches the records out of the database it actually locks those rows and no other user can fetch those rows from the database until we either commit or revert our changes that's very safe but unfortunately in the world of web browsers when people call up the screen then follow a hyperlink then fold another hyperlink then they go for lunch then the day is over and they go home and I never did save or commit pessimistic walking doesn't work very well because now all of a sudden nobody can use your database so EOF also supports something called optimistic locking and with optimistic locking we will allow two users to fetch the same record but before any user saves their changes back into the database eaf will automatically compare the record in memory against the record in the database and make sure they match and if they don't match that means someone else has made a change a neo else will throw an exception and say that we can't save those changes and within yo modeler you can use a little padlock icon it's not a suitcase and specify which particular attributes you care about in this case we don't want anybody changing the first and last name without both of them being changed or without one person having access to both of them but we don't really care about the paygrade if i want to change some of these first and last name while somebody else changes their pay grade we don't care so we have these exceptions being thrown by EOF and now we have to know how to deal with them in your class well we use the standard Java exception handling mechanism inside our Save Changes method will ask the session for the default editing context and remember the default editing context is the little pool of objects that this particular user is using and it's kept separate from every other user we'll try to save our changes and if there were any validation exceptions then we'll generate an error page displaying the appropriate error message if everything went through okay we'll return null save our changes and redisplay the current page uf also supports the concept of shared objects because as I said normally every user gets their own editing context and that's good for security the two users can't interfere with each other but it's very bad for memory as soon as we have five users hitting their database every user looking at all of the products in our catalog suddenly we've got more memory that our computer can handle so we have the concept of shared objects this is a new feature in web objects if you have a read-only entity like the product in a catalog you can mark it as a shared entity and when your web application launches up EOF will automatically fetch all instances of that entity into memory and then all of the different users will all share access to those particular objects and if by chance some user should try to change one of those objects even though it's shared that's ok EOF is clever enough to notice that and it throws one of those validation exceptions we talked about tell these though this is a read-only entity you're not allowed to edit it you'll modeler also lets us create stored procedures if there's a particular fetch operation we'll be doing over and over and over again we can build it graphically in your modeler so that was the type specification that was for ages stored procedures what we use to improve our performance so we can create stored procedures within EO modeler and then they can get triggered automatically do inserts updates and deletes and to any database triggers that we want executed we can also have fetch specifications that we use to retrieve data from the database build a once an EO modeler and then at runtime we can just reuse that fetch specification time and time again in EO modeler you'll select an entity in this case the talent entity create a new set specification and then graphically assemble the query that you want so here we want a list of all of the actors based on the movie revenues so we can actually build up a key path where are the actors where the roles movies revenue is greater than the revenue and all that actors roles movies date released are after a certain date and their movies date released is before another date and when you actually execute this fetch EOF will automatically perform the joint operations to resolve that query because we actually have three different tables involved here there's the talent table for the actor the movie table for the movie and that rules table that was a join table I told you about that actually relates Abe actor and the movies that they've been in an EO F will automatically put all that together at one time you don't worry about it you just call the fetch actor by movie revenue and your source code the way this will look is again you'll create or get hold of your editing context declare an array variable to store the results of your fetch and then use the yo utilities class this is a class that has a bunch of static methods for common operations so here will ask you utilities give me all of the objects with the fet specification and binding and pass in the name of the fad specification actor buy movie revenue and then a dictionary of key value bindings in this case the revenue and the before date now in this example we actually had an after date in our fete specification the dollar signs represent the variables that will be looked up in the dictionary so we have revenue after date and before date in our dictionary we don't provide the after date so EOF will automatically prune that particular clause out of the fete specification if you didn't provide a value we'll assume that you don't care and that's the essence of how AOF and Ile modeler work together to build your application first you use your modeler to inspect the database pull in all the data that you need to look at set up the entities describe how a particular database table corresponds to a class in your application use the o models do any custom entity work you need to do generate some sequel code maybe set up some simple validation rules in yo modeler or perhaps write some more complicated validation rules within AOF and in your java code and then finally you actually build and run the application that will be displaying your information and in fact I'll do that for you right now so we could switch over to one or number four and create a show of hands here in the audience how many people here did not see the previous presentation where you saw how ill modeler and project builder how you saw web objects folder and project builder work together how many people here did not see that so most people did good I'll quickly sketch out the details of that but I'll focus most of my attention here on yo modeler so bring up the EO modeler application and I'll create a new model I'll choose which type of database I want to connect to in this case I'll use open base light open base light is actually a filesystem database so we'll navigate off to in the file system where the database is stored and that is in local library databases the movies database and I'll say that's the database I want to use I then get to make some selections here I do want to assign primary keys to the entities I don't want to be asked about all the relationships I'll just trust UF to do the right thing I don't want to be asked about store procedures again I'll just trust ill modeler and EOF to make the right choices and I do want to use custom enterprise objects so I do want a director class a talent class and a movie class in my application on the next screen we have a list of all the tables in that database and I choose which particular tables I want to use in this model well in this particular table I want the movie and I want the movie role and the studio and the talent although EOF is going to do its best to ask all the right questions sometimes it does need to come to me for help in the case of our movie role there isn't a single column that's the primary key because that was a joint table between the movie and the talent entities so eeeh modeler comes back and tells me I don't know which of these is meant to be the primary key I'll tell it it's actually both the movie ID and the talent ID and I'll finish so now we have our L model file because this is a live demo and I am paranoid I'll save my changes right now and I'll call this 403 slash movies it will come up and tell me that the 403 directory doesn't exist I'll say yes please create that directory for me and here we are an EO modeler we can select a particular entity the movie and see a list of all of its attributes so the movie has a category the data was released the movie ID which will see is the primary key of this particular entity and it doesn't have the diamond icon and that diamond icon tells us whether or not there's going to be an instance variable in our application that goes along with that column and for the movie ID the answer is no we don't want the primary key to be visible inside the application down below we have a relationship the two movie role and the to studio relationship and I don't like those names so I will change them to the roles of the movie and the studio of the movie and we can also look at the inspector panel so if I select a particular attribute the category I bring up the inspector panel we can see the name of it is category Rory the column name in the database is all caps category external type is character and internally it's a string but we're going to limit the width to 20 characters because that's how many characters we can put into the database similarly I could select a relationship and the relationship name here is roles it's a relationship to the movie role entity and it's a one-to-many relationship so a particular movie has a relationship to many roles and we're doing the join using the movie ID and the movie ID columns of the two tables evil modeler will also let me see the diagram view that I showed you a book told you about before so here we can actually view our entire schema as a picture and if we arrange it nicely we can see the relationships between our various objects so now we see that we have the movie and the talent are connected through this movie role and that the movie also has a relationship to the single studio well we also have more than one relationship between movies and talent a movie star is a number of actors but it's also directed by a particular director and some movies have more than one director so if I select the list view and select the talent and the movie it's the talent and just the movie I can then choose join in many too many and we get another entity here called the movie talent which I happen to know because I've seen this database before it's actually called the director and the table is director and let's cancel that and now once we've done all of this we're ready to actually build an application so while high deal modeler actually before I high deal modeler I'm going to have a look at this director table and make sure it does what I think it's going to do the movie ID the talent ID the movie ID the talent ID yep that looks good and we can do a fetch and it says that there is no talent ID on director so rather than actually try to resolve what's going on I'll just take that out because we don't need it for this demo so that was the basics of how to use ill model or to explore a database pull in all the information that we needed and then construct a model file to describe the mapping between the database and our application I can put you a modeler away and bring up project builder and now in project builder I'll build a simple application that uses this data to actually display some information on the screen we'll call this the actor app and it's going to be a web objects application we'll say that we want some help building this application and we're going to be using Java and we'll open the model file that we just built so we'll grab the movies model file and because this application is called actors we want to display the talent in the database I will show a table of all of the particular actors that match our query we choose which attributes we want to display so this basic web application will go back to our previous screen is going to display a query form and then a table of results that match the query so what do we want to actually show in the table well let's show the first name and the last name and which attributes do we want the user to be able to execute a query on the last name the first name what do we want now let's say we want to query on the put that back because we want the first name to appear first and then the last name and now the assistant is going to go away and actually build a project force that once we build and execute it will give us the user interface we've asked for so I'll bring up the build panel and I'll build this application once the application is finished building put that away and we'll bring up our launch panel and we'll actually run our web objects application now after launching the server-side of the web objects application web objects is automatically going to launch a browser to display this information and it does this for your convenience as a developer when you're final steps before you ship an application and deploy it it's to go into preferences and turn off that preference so that you don't have a browser firing off on your server off in your server room and here at Omni Webb we can see our application where we can search for the talents specify what talents we want to display let's say we want everybody whose last name begins with F and we've got a list of all the talent in our database or actually all the talent is last name begins with F so that was the simplest case of bringing up ill modeler pointing at an existing database and saying please build me a database we'll work with this and then using the assistant in web objects builder and project builder to actually build an application that will display that information well the more complicated case might be if we wanted to use one of those best specifications that I told you about so we'll go back to project builder and in our resources will find the movies model file and here in our movies model file will select the talent entity and I'll say that I want to create a fetch specification that goes along with the talent and the fetch specification let's give it a name we'll call it fetch actors and we want to fetch where the first name is like dollar sign first name and that dollar sign first name means there will be a key in the dictionary whose value is the first name we care about and whose last name is like last name and whose movie role movie has the title which matches the title so we'll save this modal file now that we've added the new fetch specification and now rather than just doing query by example we can actually use this particular fetch specification in our application so we'll hi do modeler we'll go ahead at this component that project builder and web objects builder built for us automatically and this component has the query by example segment in which we specify the talents to display we set their first and last name and we have the match button and then we have the table segment where we actually construct the table using repeating rows and columns to display the information well up here what I'd like to do is create another query field so we'll say we also want to search by movie title and in fact I want to make all the fonts a bit larger there we go and I'll use the web objects builder inspector panel to say the value of this particular field is going to be the talent display group query match title and because the DES query is simply a dictionary I can associate arbitrary key value pairs in with it so now we have our application which will display all the talent that we need to display save these changes I'll add a special action because we can't use our default fetch and it's action will be called search and we'll have a look at our source code and our search action will say we'll get the default editing context this is the collection of objects that were displaying to this particular user and the dictionary that we want to use is our the query match from the display group and the results will be will use au utilities to get the objects with objects the FET specification and bindings passing the editing context the name of the entity the name of the fetch specification which I'm suspicious so I'll go back and double check yep and is called fetch actors and our dictionary of bindings and then say talent display group set object array results and the display group I won't to go into within a lot of detail but essentially the display group is an object that knows how to display objects in particular a group of objects in the case aquaria by example it built the query on the fly in the case of our query we did the query by hand so once we get the results we just hand the results to the display group and say these are the objects that you'll be managing thank you that's actually great correct Java code here we'll build the application we'll launch the application and now we could again ask for all the actors whose names begin with F by typing an F asterisk or if we just want to just know all the actors in a particular movie we could say we want to know all the actors in the movie star wars and it tells us that there is no title available and since I have only one minute left I'm going to say I'm not going to bother trying to debug this and instead I'm going to fight Steve up on the stage and we'll have the question announces you