Task 2: Persisting Employers and Skills
You will need to have completed the setup steps before starting this section.
AbstractEntity
We’ve replaced the abstract class JobField with an even more abstracted class aptly named,
AbstractEntity. This class holds the fields and methods that are common across the Job class
and the classes it contains as fields.
- We will be creating tables for the subclasses that inherit from
AbstractEntitybut not a table for this parent class. Therefore, giveAbstractEntitythe@MappedSuperclassannotation. - Since all of the subclasses of
AbstractEntitywill be entities themselves, add the@Idand@GeneratedValueannotations to the fieldid. - Each subclass will also inherit the
namefield fromAbstractEntity. Add appropriate validation annotations so that:- a user cannot leave this field blank when creating an object.
- there are reasonable limitations on the size of the name string. Keep in mind that the name field will be shared across
Job,Employer, andSkillclasses. Some employer names might be longer than 50 characters.
Models
In the last assignment, a Job object contained string fields for employer and core competency data. This employer
and skill (formerly core competency) information about a particular job will now be stored in classes themselves.
These items themselves will hold their own supplementary information.
- Open the
Employermodel class. In addition to the fields inherited fromAbstractEntity,Employershould have a string field forlocation. Add the field forlocationwith validation that ensures it is not empty and has a reasonable length. In addition, add public accessor methods toEmployer.
For the purposes of this application, an employer can only have one location.
Employeris a class that will be mapped to one of our tables. Make sure the class has the@Entityannotation, as well as the no-arg constructor required for Hibernate to create an object.- In the model class
Skill, add a field for a longer description of the skill, nameddescription, with public accessor methods. Some hiring managers like to have more information available about the nature of a given programming language or framework. - As with
Employer, give this class the@Entityannotation and be sure it contains a no-arg constructor.
Data Layer
To map the Employer and Skill classes to your techjobs database, you’ll add data access interfaces for these relational
objects, similar to the existing JobRepository interface. Like JobRepository, make use of the Spring Data CrudRepository interface to map our objects.
- In
models/data, create a new interfaceEmployerRepository.
EmployerRepositoryshould extendCrudRepository.EmployerRepositoryshould be annotated with@Repository.
- Repeat the steps above for an interface,
SkillRepository.
Controllers
The tests in TestTaskTwo relating to the following tasks have been commented out because they depend on the code you wrote earlier. Open TestTaskTwo in IntelliJ and find these tests. For each one:
- Select the entire commented-out method. These methods start around line 328. You may need to add
importstatements for some of the classes used in these methods. - Uncomment the method by using
cmd+/on Mac orctrl+/on Windows. If you do not uncomment these tests, your code will not pass the autograder. Uncommenting these methods will introduce some new errors related to a class namedSkillController, but these will be fixed by the code you are about to write. If you like, you can leave these commented out until you get to that task.
With the employer repository in place, we will reference this to send object information through
the EmployerController handlers. EmployerController contains two handlers with missing
information. Your task here is to make use of the EmployerRepository class in these handlers.
- Add a private field of
EmployerRepositorytype calledemployerRepositorytoEmployerController. Give this field an@Autowiredannotation. - Add an
indexmethod that responds at/employerswith a list of all employers in the database. This method should use the templateemployers/index. To figure out the name of the model attribute you should use to pass employers into the view, review this template. processAddEmployerFormalready takes care of sending the form back if any of the submitted employer object information is invalid. However, it doesn’t yet contain the code to save a valid object. UseemployerRepositoryand the appropriate method to do so.displayViewEmployerwill be in charge of rendering a page to view the contents of an individual employer object. It will make use of that employer object’sidfield to grab the correct information fromemployerRepository.optEmployeris currently initialized tonull. Replace this using the.findById()method with the right argument to look for the given employer object from the data layer.
The variable holding the id you want to query for is already provided for you in the controller method’s parameters.
- Create a
SkillControllerclass and replicate the steps you followed above forEmployerController. The new controller should have the methods,index,displayAddSkillForm,processAddSkillForm, anddisplayViewSkill. These methods should behave exactly as the corresponding methods inEmployerController. The relevant templates have already been created for you.
At this point, uncomment all remaining methods in TestTaskTwo, if you have not done so already. You’ll need to add an import statement for the new controller to the test file.
Test It with SQL
The employer and skill view templates for adding and viewing these objects are made for you. Before you move on, test your application now to make sure it runs as expected. You should be able to create Employer and Skill objects and view them.
Start up your application – don’t forget to have your SQL server running – and go to the
Add Jobsview from the application’s navigation menu.You won’t be able to add a job yet, but you’ll see a link to
Add EmployersandAdd Skillsin the form. Click them and proceed to check the functionality of the forms that follow.Be sure to test your validation requirements and error handling.
SQL TASK: In
queries.sqlunder “Part 2”, write a query to list the names of the employers in St. Louis City. Do NOT specify an ordering for the query results.
If everything seems to work – that is, you are able to submit the form without any errors – but you don’t see your employers or skills in the list after submission, here’s what you should check:
- Is there any data in the
employersandskillstable? Check by going to MySQL Workbench and looking for the employer/skill data within your schema. - If there’s data in the database, check that you are correctly querying for the list of all objects in the controller. Are you calling
.findAll()on the repository? - Ensure you’re passing the list into the view, and it is named the same as the variable in the ThymeLeaf template.
When everything works, move on to Part 3 below.
Throughout your work, refer to the demo app as needed.