JPQL/ JPA Activity 2

25
Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4 DATA AWARE TASK Step by Step Guide for Java Version 0.4 J. Tangkuampien Open-Licence 2014 J. Tangkuampien http://creativecommons.org/licenses/by-nc-sa/2.5/za/ Based partly on scenario and data from the IEB matric practical paper – November 2009

Transcript of JPQL/ JPA Activity 2

Page 1: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

DATA AWARE TASK

Step by Step Guide for Java Version 0.4

J. Tangkuampien

Open-Licence 2014 J. Tangkuampien http://creativecommons.org/licenses/by-nc-sa/2.5/za/

Based partly on scenario and data from the IEB matric practical paper – November 2009

Page 2: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Task 1 – Database Design & Creation

Required: Excel spreadsheet containing normalised database (2 tables each with primary key and a one-to-many relationships ie. Foreign key à primary key link)

Output: Java DB database that reflect the tables contained in the spreadsheet.

We are going to be using the Pet-Owner example in these descriptions. This is a one-to-many relationship where one pet only have one owner but one owner can have many pets. This results in the PET table containing a foreign key field OWNERID which is linked to the primary key (also named OWNERID) of the OWNER table.

Important: When choosing designing your database:

• Make sure that each table has a numbered primary key • The names of your database and tables are in capitals and contains no spaces, no

SQL and Java reserved keywords or any illegal characters. • The foreign key field values all exists as primary key fields in the related table.

Step 1.1 – Decide on type of column for the two tables. Since the PET table contains link to OWNER, we should create the OWNER table first before the PET table.

Step 1.2 – Create a new JavaDB Database by going to the “Services” tab (Window à Services if you can’t see it. In the tab, expand “Databases”, and choose “Create Database”. In the dialog box that pops up, choose the database’s name, leave the Username and Password as blank. (Note that NOT choosing a password here will complicate things later so it is best to leave everything as blank). Take note of the database location (You can click “Properties” to change this.

Comment [1]: It  is  important  that  there  is  a  primary  key  field.  You  can  not  generate  entity  class  from  a  table  without  a  primary  key  field.  

Comment [2]: SQL  reserved  words  will  turn  BLUE  in  the  SQL  command  execution  window  (see  Step  1.4  on  how  to  get  it).  It  is  possible  to  override  and  use  reserved  words  as  table  or  column  names  if  you  put  them  in  quotes.  Do  NOT  do  this  because  things  will  break  later  on.  To  check  for  Java  reserved  word,  type  it  in  Netbeans  file  edit  windows  and  see  if  it  is  BLUE.  

Page 3: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Step 1.3 – Once the database is created, you will need to connect to it. This can be done by locating the connection which should be just below the “Driver” folder. The one you created should end with the name of the database. Right-click on it and choose connect. A username/password window will pop up. Just click ok as your password is blank.

Step 1.4 – We will now create a new table in the “APP” schema using SQL. You should make the “APP” schema the default one by right-clicking and choose “Set as Default Schema”. If APP is already bold (see below) then it is already default. To create a new table in APP using SQL, right-clicking on the “Tables” folder (or APP) and choose execute command (Do not choose Create Table). This will open up an edit window on the right. Type in the appropriate create command. (VARCHAR is text with the number between the brackets indicating its size). Run the command by clicking on the “run SQL button” (not the same as the run project button).

If there are any errors, read the error message and correct the command. Once you can run this successfully, save the SQL statement to a file in case you need to recreate the table for whatever reason. Clear the command window after you have done this.

Note that you can choose to start from a different number and not always from 1.

Comment [3]: It  is  possible  to  use  the  GUI  to  create  table,  but  certain  functions  such  as  creating  a  auto-­‐numbered  fields  are  only  available  via  SQL  currently.  It  is  better  to  create  using  SQL  in  any  case,  because  you  will  be  able  to  save  the  SQL  for  back-­‐up  purposes.  

Page 4: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Step 1.5 – You will need to create SQL commands to insert data into your table. The easiest way to do this is via Excel as shown below. Do this with one line first to make sure that this works. Also make sure your command ends with semi-colon so you will be able to have multiple statements.

Copy the command to the SQL window. You will notice that Excel has automatically add tabs in between the cells.

You can do a search and replace for tab by using Edità Replace (or Ctrl-H). Search for backslash t (see below) and leave the replace with blank. You will need to turn on use regular expression to make this work. To do that, click this button. If you have done this correctly, all tabs will be highlighted – click replace all.

All tabs should now be gone from the command. Run it and make sure that it works.

Make the necessary correction to the first row before copy and pasting the commands to the rest of the sheet. Copy and paste the commands (except the first since you have done that) and follow the same procedure as before to get rid of the tabs.

Comment [4]: Alternatively  you  can  use  the  concatenation  command  in  Excel  to  create  a  cell  with  all  the  others  concatenated  together.  This  will  save  you  from  having  to  get  rid  of  the  tabs  as  shown  previously.  

Page 5: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Step 1.6 – Create the other tables in the same way. Remember to match the type of any foreign key field with that of the corresponding primary key. In our example, OwnerID is an INTEGER. Other types you may want to use are DOUBLE, DATE and BOOLEAN. All of these can be used standalone with no argument provided (like INTEGER)

Step 1.7 – Once all the tables are created, run the command below to link the keys. Note that you should alter the table containing the foreign key (line 1). Line 3 refers to the foreign key fields in the table you are altering and line 4 contains the references to the primary key – REFERENCES Table (primary key). Test that the relationship is working by inserting a new Pet with an non-existent ownerID and delete an Owner record that a Pet linked to it. These action should not be possible.

Step 1.8 – Disconnect and delete the connection entry in the services list. We will be create a new one in the next task. Note that deleting the connection does not delete the database. You can still find the database folder by going to the database location folder. It is recommended that you also delete any other connections at this point so that you are not confused by which one to choose at a later stage.

Table  with  Foreign  key  

Table  with  Primary  key  

Foreign  key  field  

Primary  key  field  

Page 6: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Task 2 – Linking the Database to a Java Application

These steps should be done all in one go in order to ensure that the projects are transferable to other locations.

We will now create Netbeans application and then add an embedded database to it. We will be using the PetDB we created earlier.

Step 2.1 – Create a new Netbeans Project – Java Application is fine. Locate the PetDB database folder in your copy. Copy the PetDB database folder into the project folder. The project folder is the one listed under properties. You should also be able to see other folders (nbproject, src) in the project folder. You will need the exact path to the database folder (including the folder name – PETDB in this example) in the next step.

Step 2.2 – In the service tab, under driver, right-click on “Java DB (Embedded)” and then “Connect Using ..”.

In the window that pops up, enter the exact path to your database folder (including the database name) and click “Test Connection”. If your connection is successful, you will see “Connection Succeeded” on the bottom left.

If not, check that you have enter the correct path (You must indicate the database folder and not the folder that contains the database folder. The correct database folder will contain ‘log’ and ‘seg0’ folders. Also check that you have not made a spelling mistake. Once the test is successful, click “Finish”

In the next window that pops up, make sure “APP” is selected as the default schema. If you did not do this at this stage, you can at a later stage make APP the default one as before (See Step 1.4).

Page 7: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Step 2.3 – We will now create entity classes from the database. To do this, right click on the package icon (see below) of your project and choose New à Entity Classes from Database

In the window that pops up, make sure the Database connection is the one you have just created in step 2.2. The correct entry should NOT link to localhost. After making sure that the database selection is correct, you should see your tables listing in ‘Available Tables’ – add all the tables to your solution (Click “Add All >>”)

You may change the name of the entity classes that will be generated here if necessary. For example, if you have named the table “OWNERTB”, you may want the class to be called “Owner” instead of “Ownertb”.

Comment [5]: Choosing  an  incorrect  connection  here  will  result  in  your  program  not  working  and  it  will  be  rather  difficult  to  correct  this  without  starting  again  from  this  step.    

Comment [6]: This  will  ensure  that  the  class  you  created  from  the  table  has  more  sensible  name.  It  is  more  sensible  for  each  PET  to  have  an  OWNER  than  for  each  PETTB  to  have  an  OWNERTB.  Note  that  most  assignments  including  your  main  PAT  requires  that  you  name  everything  sensibly.  

Page 8: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

The following changes are recommended for the Mapping Options:

Use java.util.List as collection Type. This will result in each Owner object having a List of Pets that he/she owns.

Uncheck “Use Column Names in Relationships”. This will generate an attribute of type Owner in the Pet class called Owner instead of

Ownerid. (This name choice will also be in the get/set methods. This choice makes more sense as you will actually beworking with the action Owner object and not its ids.)

After this, you should be able to see the two new entity classes listed under the project package. Have a look at what Netbeans generated. You should get the same attributes as the database fields as well as constructor, get, set and toString methods. Note that the computer did not generate a constructor that takes in all attributes.

IMPORTANT: Note about boolean type

When one of the type is a boolean, Netbeans will errornously create that attribute as type “Serializable” instead of boolean. You will need to edit the generated Entity class file and replace the attibute type “Serializable” with type “boolean” (with small b). Also modify the get and set methods to reflect this. Do not just do a search and replace all “Serializable” with “boolean” – there are other instances of “Serializable” that must stay. Do a clean and build before continuing.

Page 9: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Step 2.4 – The next step is to create a JFrame Form that will have all the GUI elements.

Add a JTabbedPane to the JFrame. Rename the added JTabbedPane according to convention (i.e. tbpTabs or something similar). You can then drag and drop a JPanel on to the JTabbedPane. This will create new tab. Rename the added JPanel and change its text to “Owners”. We will be using this tab to display all of the owner information in a table form.

Add another JPanel to create a new tab, but be careful not to drop the JPanel on to the existing tab, you must drop it onto the JTabbedPane so drop it here and NOT here

Make sure you have 4 tabs as shown above. Remember to rename each JPanel as you add them.

Comment [7]: Note  that  the  Java  classes  corresponding  to  the  components  in  the  pallete  are  all  actually  named  with  J  in  front.  In  these  notes,  all  the  interface  components  are  referred  to  using  its  Java  class  name  i.e.  JPanel  instead  of  Panel,  JTable  instead  of  Table,  JList  instead  of  List  etc.  

Page 10: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Step 2.5 – We will now work on the first tab which will display all of the owner information in a table form. To do this, go back to the first tab and drag and drop a new JTable on to its JPanel. Resize the JTable so that it takes up all available space in the JPanel. Also rename this JTable appropriately.

This JTable’s content will be bounded to the OWNER table in the database. This means that the content of the JTable will always reflect the content of the OWNER table in the database. To do this, right click anywhere on the interface table and choose “Bind”. We are going to bind all elements to the database table, so choose “elements”.

You will then see a Bind dialog box, choose “Import Data to Form”. In the next popup window, choose the correct database connection (be careful to choose the same one you used to generate the Entity classes). In the Database Table drop down list, choose the correct table (OWNER in this example). Click “OK” to move on.

Page 11: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

You can now choose which fields to be included; typically you will want to add all fields. For some reason the list is always displayed in reverse so you may need to move things up and down to choose the correct order. Click “OK” once you are happy with the ordering. Note the petList field that will contain all the pets that belong to this Owner.

Step 2.6 – We will now attempt to run the program to see if the interface table has been populated correctly. If you just see a “build successful” message without the JFrame popping up it may be because you asked Netbeans to create a main class for you. If this is the case, you will need to delete that class (it should have an empty main method in it). When you run the program again, it will ask you for the new main class to be use – choose the JFrame class.

Comment [8]: It  is  shown  as  PetCollection  in  the  diagram.  

Page 12: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

The program should attempt to start the frame and show a “PersistenceException” in the process.

This is because Netbeans itself is connected to the embedded database (by definition and embedded database is only accessible by one program at a time – usually by the program (or any of its threads) that it is embedded in). To correct this error, you will need to go back to the services tab and disconnect Netbeans from the database.

Every time you ask Netbeans to link to the database (eg to Bind or generate entity classes) – Netbeans will make a connection to the database. So make sure to check for disconnection as Netbeans may have made the connection previously.

Note that you will also get the same error if you attempt to run a second instance of your program.

Once run successfully, you should see all the information on each owner. Note that the PetList field does not contain the list as yet.

Comment [9]: This  is  because  you  choose  the  default  fetch  type  when  generating  the  entity  classes.  If  you  want  the  list  to  be  visible  at  the  start,  you  could  have  chosen  eager  as  the  fetch  type.  However,  this  does  NOT  make  a  difference  to  your  task  and  is  not  worth  going  back  to  change  it.  Lazy  fetch  type  means  that  the  content  of  the  list  will  only  be  fetched  whenever  that  object  is  requested  and  not  right  at  the  start.  You  can  see  the  reason  why  you  may  not  want  to  fetch  everything  at  the  start  if  your  database  table  contains  thousands  of  records.  

Page 13: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Step 2.7 – You will now add another JTable to the PETS tab. (Drag and drop JTable to tab, rename, right click à Bind à Elements. Choose the correct connection (same one as before) and choose the PET table, then add and reorder column).

When you run again (don’t forget to disconnect), the Pet JTable should be populated.

You can edit to the toString method of the Owner class to make it output the name and surname instead of the default one seen above.

Page 14: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Step 2.8 - The binding process created 5 new components in the JFrame. Look for them in the Navigator.  Two of them are Lists which are the data structures behind the two JTables. We will need to make these Lists updated automatically when the database changes. To do this, right click on each list and choose ‘Properties’.

In the properties window, tick both ‘modifiableWrapper’ and ‘observable’.

Do this for the List that is linked to the other JTable as well.

Do a clean a build and you should see no changes to the JTables.

Step 2.9 – Test that you are able to edit the information in each cell by clicking twice on the cell. The changes should be reflect but does not persist across restart of the program. This is fine as we have not yet done the persistence part. We will do this in the next task.

Step 2.10 – After you have bounded all each database table to a JTable, delete the Connection from the Database section in the Services tab. This is so that you do not make a mistake of choosing this in future. Make sure no other connection exists.

Comment [10]: This  will  allow  the  list  to  be  modified  as  the  interface  changes.  

Comment [11]: This  will  allow  the  content  of  the  List  to  be  observable  so  the  linked  interface(s)  can  be  updated  accordingly.  

Page 15: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Step 2.11 – Recall that the database folder information was hard-linked to the DB folder by specific path. This means that the project is currently not running when moved to a different computer. This last step will make the path relative so that you can run the project in other location.

To do this, expand the “META-INF” folder found within the project folder. In that folder, open the file “persistence.xml”, click on the source tab.

In the source edit the url property and remove any absolute path – leaving with just the name of the database

Test that your program still runs correctly.

Page 16: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

You should also copy derby.jar file to your project folder and then add this file to the library in your project. This is necessary if your Netbeans is not the exact same version as the one used at school.

If you can’t find a copy of derby.jar – search for one in your computer. There must be one if you connection is successful.

Copy this file to your project folder i.e. in the folder with build, nbproject, src etc (see right).

After that, right-click on “Library” in your project tab in Netbeans and choose add JAR/Folder.

Select derby.jar from the right window. Make sure you choose to reference as “Relative Path”.

Even if you have done this step, opening your project in other computer initially may result in a missing reference error. Your project should still work without resolving this error. You can also resolve it by telling Netbeans where derby.jar is (it should be in the project folder because you just copied it there).

Page 17: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Task 3 – Other interfaces

Before we go on with this task – note that by binding to the two database tables previously, Netbeans has created for us to data structures (of type List) i.e. a List of Owners and a List of Pets. You can see them in the Navigator window, under other components. (ownerList and petList). Note that you should only have one of each. If you have more than one then you may have done one of the previous steps more than once.

These Lists are linked to the database tables and should be used from this point on to bind additional interface components. DO NOT bind any additional component via the “Import Data to Form” button. Instead, you should select either ownList or petList from the drop down list as the binding source.

Step 3.1 – We will start off with the “edit Owner” tab so that it ends up looking as shown below. The component of the left is an interface list (JList) that will be bound to the data structure List ownerList (which in turn is bound to the database table OWNER). Selecting

an owner from that JList will show that owner’s attributes on the right. The component next to Pets is also a JList. The <<, <, > and >> buttons will take the user to the first, previous, next and last item on the left JList respectively. The other buttons are self-explanatory. Start off by adding, positioning and chaning the text on the components as shown. Also remember to name each component appropriately (eg. txfFirstname, txfLastName, btnAddNewOwner etc.)

Page 18: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Step 3.2 – We will now bind the JList to the ownerList as follows. Right click on the JList and choose Bind à elements (all of the elements in the list will reflect the content of ownerList). DO NOT click on “Import Data to Form” and rebind the database table.

Once bound, you can run the program and should see the following. The toString method is used for display as before.

Note that there are now two interface components (the JTable in the OwnersTab and the JList in this tab) that are bound to the same ownerList which in turn is bound to the database table OWNER. The JList in the above tab is named “lstOwners”.

The diagram to the right summarises the link between the JList (User Interface), lstOwners (data structure) and OWNER table (database).

For the rest of the document, the data structure list will be referred to as List (or List<Owner>) and the interface list will be referred to as JList. Netbeans normally name your data structure list as <name of entity class> followed by List. Your interface List (JList) should be named with lst prefix as recommended.

Comment [12]: If  you  do  this  again,  you  will  get  another  EntityManager,  List  and  Query  objects  associated  with  this  JList.  Do  NOT  redo  that  step  (unless  you  really  want  new  copies  of  those  three  things)  

Comment [13]: It  is  possible  to  use  Binding  Expression  in  the  binding  window  to  choose  exactly  what  the  JList  will  show.  Do  NOT  do  this  because  if  you  do,  the  JList  will  be  linked  to  a  List  of  Strings  instead  of  a  the  List  of  Owner  objects.  

Page 19: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Step 3.3 – The next step is to bind all the components on the right to reflect the attributes of the selected owner on the left JList.

We will start with the Owner First name Text field. Right-click on the text field and choose “Bind” and then “Text”

The text will be bound to the selected item of the JList (and not ownerList or any other List or JList) – so select the list (lstOwners in our case) as the Binding Source.

In the binding Expression, navigate to “SelectedElement” and “ownerfirstname”.

Once bound, run the program and check that the first name changes as you move up and down the list.

Do the same thing for the other text fields. You should also bound the Pet JList to the petList attribute of “SelectedElement” as well.

Comment [14]: It  is  important  to  choose  the  right  thing  to  bind  to  -­‐  List  vs  JList.  The  general  rule  is  to  think  about  whether  or  not  you  need  the  selected  item.  Only  a  JList  knows  which  item  is  currently  selected  –  so  if  you  need  to  know  which  item  is  selected  currently,  use  a  JList.  If  you  don’t  need  to  know,  use  the  List.  

Page 20: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Run the program and make sure everything works as expected.

Use the following components to bind to the different data types:

• Single line String – use JTextField • Multiple line String – use JTextArea (JTextPane if the user shouldn’t be able to

change it) • double or ints – use JSpinner (with model set as numbers) • Date – use JFormattedTextField or JSpinner (with model set as Date) • boolean – use JCheckBox • List of objects:

o Use JComboBox (if user can select only one item – useful for one to many relationship – eg. In Pet window where there can only be one owner).

o Use JList (if user can select multiple items – useful for the other side of the relationship – eg. In Owner where they can have many pets.)

We will now add code to the Navigational and Search buttons. We will deal with the other buttons in the next task.

Page 21: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Step 3.4 – Navigational Buttons

Code the action for the navigational buttons. The following points may come in handy:

A List<Owner> allows you to work with the data in the List. Use the following methods:

• get(int  pos) – will give you back the Object (Owner in our case) at the given position.

• size() will give you the size of the List at the moment.

A JList allows you to get and set selected item on the JList. Use the following methods on a JList

• getSelectedIndex() will give you the index (position) of the selected item (it starts from 0).

• getSelectedValue() will give you the object (but you will have to cast it to the correct class e.g

Owner  selectedOwner  =  (Owner)lstOwners.getSelectedValue();  

• setSelectedIndex(int  pos) – let you set the selected item to the given position. However, the list does not autoscroll to that item (see next one for how to do this).

• setSelectedValue(Object  o,  boolean  autoscroll) will let you select an item and also allow you to scroll to that position. You will need to locate the object first which can only be done via the List ownerList. For example, this code will set the selection to the first item on the JList.

Owner  firstOwner  =  ownerList.get(0);  lstOwners.setSelectedValue(firstowner,  true);  

Step 3.5 – Add code to the search button to allow items matching the search criterion to be selected. To fit in with the task requirement, you only need to search for one attributes of the entity class (eg. Search for last name of the owner). You can do the search by using a loop and testing if each object matches the given criterion. You only need to select just ONE matching object, so the first one you find is fine. Use setSelectedValue method to choose the matching object.

Step 3.6 – Do a similar thing for the “Edit Pets” tab. We will do the add, edit and remove buttons in the next task.

Page 22: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Task 4 – Update, Remove, Add and Search Buttons

You will now work on the Update, add and remove buttons in the “Edit Owners” tab.

Update

Update operation will depend on whether or not there is a selected item in the JList. Your code should check for this before attempting update (or you can set up your interface so it is never possible to update while no Owner is selected). There are many ways to do update but you should aim to the user to not be able to move away from the selected item (or delete or add new item for that matter) while he is editing. It may be easier to:

• Disable the attribute fields by default until the user click the update button.

• Once clicked, the fields should then be editable and the update button’s label changed to “Commit”. The other buttons (navigational, add and remove) should be disabled so that the user can not move away or attempt to do other operation.

• The user can then edit the field and click on “Commit” (labelled “Update” previously). On commit, you program will do the reverse of the previous step (e.g. disable the fields, enable the list and the other buttons as well as change the label of the Update button back. Note that since the text fields are already bounded to the selected object, any changes made to it already updates the selected object. All this is left is to make sure the object is changed in the database. Here are some hints on how to do this:

o Use getSelectedValue() method on the JList to locate the selected Owner (You will need to cast as getSelectedValue() returns an Object) and then use set methods to update the attributes to the new values indicated by the user.

o Use the following code to update the OWNER database table. You will need to make use of the Entity Manager (who manages the link between the database and the List) to do these steps. If you are not sure of the name of the Entity Manager, look in the Navigator under “Other Components”. The Entity Manager in our example is called “PetAppPUEntityManger”. Here is the update code:

PetAppPUEntityManger.getTransaction().begin();  PetAppPUEntityManger.persist(selectedOwner);  PetAppPUEntityManger.getTransaction().commit();  

If the interface JList does not immediately reflect the changes, you may have fogotten to change the properties observable and modifiableWrapper of ownerList and petList to true (See Step 2.8)

Comment [15]: Note  that  the  task  does  NOT  require  you  to  do  this.  

Comment [16]: Note  that  this  step  is  NOT  necessary  in  this  example,  since  you  have  bounded  the  textfields  (and  the  other  components)  to  the  selected  item  of  the  JList.  Since  the  binding  is  two  way,  the  selected  object’s  attributes  would  have  already  been  updated.  However,  if  your  component  is  not  bounded,  you  will  need  to  call  the  set  methods  explicitly.  

Comment [17]: Note  that  this  line  is  strictly  not  needed  since  the  object  is  already  binded  to  the  table  and  as  such  the  record  in  the  table  will  already  be  updated  once  you  commit.  

Page 23: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Insert New

On insert, your first aim is to create a new Owner object with the values given by the user. The automatic Entity class creation process created two constructors Owner() and Owner(int id). You should use the first one and then use set methods on the new object to set the other attributes. Do not set the ID attribute as this will be automatically done by the database.

Once you have created the new Owner object (assumed to be called newOwner in the code below), you can similar code to above to persist the new object.

PetAppPUEntityManger.getTransaction().begin();  PetAppPUEntityManger.persist(newOwner);  PetAppPUEntityManger.getTransaction().commit();  

However, since ownerList does not update automatically, we will have to manually insert the new object in it too by using the following code.

ownerList.add(newOwner);  lstOwners.setSelectedValue(newowner,  true);  

The last line selected the newly inserted owner.

An alternative (but less efficient way) to update ownerList is to clear the list and then readd all of the items using this code:

ownerList.clear();  ownerList.addAll(ownerQuery.getResultList());  lstOwners.setSelectedValue(newowner,  true);  

Deleting

Deleting operation involving entities linked via a relationship can be problematic and is dependent on how the requirements. For example, what should happen when the user try to delete an owner that has multiple pets linked to it. Should the pets be deleted as well?

The easiest way to handle this is to delete all the associated pets (maybe after a warning). You can tell Java to do a cascade removal of any pet associated with an Owner on deletion an owner by taking the following steps.

• In the Owner class, look for the declaration of the petList attribute. • Above that should be a command starting with @ that looks like this:

@OneToMany(mappedBy  =  “ownerid”)  

  Add another key to it as follows:  

@OneToMany(mappedBy  =  “ownerid”,  cascade=CascadeType.REMOVE)  

Comment [18]: Be  careful  if  you  choose  to  let  the  user  enter  new  attributes  into  the  components  that  are  bound  to  the  selected  item  of  the  JList.  Make  sure  that  you  have  NO  selected  item  when  you  add  a  new  object  ,  otherwise  you  will  be  editing  both  the  attributes  of  the  selected  object  and  the  new  object.  Use  clearSelection()  method  in  the  JList  to  clear  any  selection.  

Page 24: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

You may need to do additional import (for the class CascadeType). Once this line is added, the removal of any Owner will also trigger of automatic removal of his/her Pets.

Since the remove operation require a selected item in the JList, you will need to first make sure you have a selection. Use the following code on the selectedOwner to remove the Owner (and his/her Pets).

PetAppPUEntityManger.getTransaction().begin();  PetAppPUEntityManger.remove(selectedOwner);  PetAppPUEntityManger.getTransaction().commit();  

However, since ownerList does not update automatically, we will have to manually update it using the following code.

ownerList.remove(selectedOwner);  

You may want to make the JList select another item (or you must manually reset the attribute fields as they will still reflected the deleted owner’s attributes.

Also if the owner have any pets, all of the pets would have been removed too. However petList would be out of date so you will need to remove the pets or just reset that list. It might be easiest to do the following code:

petList.clear();  petList.addAll(petQuery.getResultList());  

Page 25: JPQL/ JPA Activity 2

 

Open-Licence 2014 J. Tangkuampien Data Aware Task – Step by step Guide for Java http://creativecommons.org/licenses/by-nc-sa/2.5/za/ version 0.4    

Possible Errors If you get errors you can not fix, it may be one of the following issues:

Persistence Exception: Database is already connected

Only one program can be connected to the database at the same time. Check that you don’t already have a copy of your program running or that Netbeans’ services tab don’t already have a connected connection to the same database.

Persistence Exception: Check for existence of the lock file

Check the database folder for a .lck file. If you copy the database when it is connected, you would have copied the .lck file as well. This file indicates to Netbeans that there is a connection. If you have made sure there isn’t any other connections, you may try to delete this .lck file. (You may need to close Netbeans to delete).

Persistence Exception: Some related SQL errors

Check that your table and fields don’t have spaces or any SQL or Java keywords (or any illegal symbols) or that your linked foreign key field values actually exist in the primary key table.

Persistence Exception: Missing library (eg Java persistence, Derby etc)

Copy the file derby.jar file (search for it on your computer or download one from Moodle) and put it in your project file (see Step 2.10).

No table listed in binding window: Make sure you DB has a default schema (APP)

If you don’t have a default schema, the binding window will not show any available database

tables. If this is the case, you did not tell Netbeans that APP (or whichever schema you created your table in) is the default schema. To fix it you will need to connect back to the database in the Services tab and set the default schema. Once this is done, you will be able to select the table.

Bound components are not updating after persisting

Check that you only have one entity manager as well as one list and one query object for each entity class. If you have more than this, you have done one of the steps too many times (or have moved to a different computer and then try to resume incorrectly). To fix this, delete all the entity manager, lists and query object and the JTables for each entity class – then try and do all the binding again.

You have List of Strings (or int or other types) instead of List of Entity objects

If for some reason, your List (of Owners or Pets for example) contains Strings instead of entity objects, then you have used a binding expression in the JTable or JList. Do not use binding expression because they will make the underlying List a List of String. To fix this, you will need to redo the binding task. See previous answer for how to do this.

You get a List cannot expand in size error when adding an item to a List

You list can only expand automatically if you tick the modifiableWrapper in its properties window. (See step 2.8). While you are there, make sure observable is also checked. If you are lucky, you will be able to fix this without having to redo your project. Make sure you do a clean-and-build after you tick though.