Get list within a list using Thymeleaf - spring

I have two tables one names "State" another named "City"
My city model
#Entity
#Table(name = "city")
public class City implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String city;
#ManyToOne
private State state;
public City() {
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCity() {
return this.city;
}
public void setCity(String city) {
this.city = city;
}
public State getState() {
return this.state;
}
public void setState(State state) {
this.state = state;
}
}
my state model
#Entity
#Table(name = "state")
public class State implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String state;
#OneToMany(mappedBy = "state")
private List<City> cities;
public State() {
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getState() {
return this.state;
}
public void setState(String state) {
this.state = state;
}
public List<City> getCities() {
return this.cities;
}
public void setCities(List<City> cities) {
this.cities = cities;
}
public City addCity(City city) {
getCities().add(city);
city.setState(this);
return city;
}
public City removeCity(City city) {
getCities().remove(city);
city.setState(null);
return city;
}
}
my CityRepository
public interface CityRepository extends CrudRepository<City, Long> {
List<City> findByState(String city);
}
my StateRepository
public interface StateRepository extends CrudRepository<State, Long> {
List<State> findByState(String state);
}
my controller
#Controller
public class IndexController {
#Autowired
StateRepository stateRepository;
#Autowired
CityRepository cityRepository;
#RequestMapping(value = "/", method = RequestMethod.GET)
public String index(Model model) {
model.addAttribute("title", "");
Iterable<State> stateIterable = stateRepository.findAll();
for (State state : stateIterable) {
System.out.println(state.getState());
}
model.addAttribute("stateIterable", stateIterable);
return "index";
}
}
and the relevant code for Theymeleaf
<div class="col-md-4">
<div class="panel-group" id="panel-790692">
<th:block th:each="state : ${stateIterable}">
<div class="panel panel-default">
<div class="panel-heading">
<a class="panel-title" data-toggle="collapse"
data-parent="#panel-790692"
th:href="|#panel-element-${#strings.replace(state,' ','-')}|"
th:text="${state.state}">State Name</a>
</div>
<th:block th:each="city : ${state.getCities}">
<div th:id="|panel-element-${#strings.replace(state,' ','-')}|"
class="panel-collapse collapse in">
<div class="panel-body" th:text="city.city"></div>
</div>
</th:block>
</div>
</th:block>
</div>
</div>
Right now I am getting this error
"Property or field 'getCities' cannot be found on object"
Is it possible to get the cities and loop through the cities using Themeleaf? If so how can it be done?

Try with replacing ${state.getCities} with ${state.cities}
<th:block th:each="city : ${state.cities}">
<div th:id="|panel-element-${#strings.replace(state,' ','-')}|"
class="panel-collapse collapse in">
<div class="panel-body" th:text="city.city"></div>
</div>
</th:block>

Related

Thymeleaf access object in outerloop from innerloop

i am looping through a list of "roles" , inside each one i loop through a list of "notifications" ( a role can have many notifications )
<div class="row justify-content-center">
<div class="col-sm-3" th:each="role : ${roles}">
<div class="card">
<div class="card-body">
<h5 class="card-title" th:text="${role.name}"></h5>
Notifications :
<div class="input-group mb-3">
<th:block th:each="notif : ${notif_list}">
<div class="custom-control custom-control-inline">
<input type="checkbox" class="custom-control-input"
th:id="${notif.id_notif_type}"
th:value="${notif.id_notif_type}" th:field="${role.notifs}">
<label class="custom-control-label" th:text="${notif.type}"
th:for="${notif.id_notif_type}"></label>
</div>
</th:block>
</div>
</div>
</div>
</div>
</div>
i want access an object "role" inside the notification loop by using th:field="${role.notifs}
here is my Role class :
#Entity
#Table(name = "roles")
#Transactional
public class Role implements Serializable{
public Role() {
}
public Role(Integer id, String name) {
super();
this.id = id;
this.name = name;
}
#Id
#Column(name = "role_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
#ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
#JoinTable(name = "roles_notifs", joinColumns = #JoinColumn(name = "role_id"), inverseJoinColumns = #JoinColumn(name = "notif_id"))
private Set<NotifType> notifs = new HashSet<>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<NotifType> getNotifs() {
return notifs;
}
public void setNotifs(Set<NotifType> notifs) {
this.notifs = notifs;
}
public void addNotif(NotifType notif) {
notifs.add(notif);
}
public void removeNotif(NotifType notif) {
notifs.remove(notif);
}
#Override
public String toString() {
return name;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Role other = (Role) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
i got an error on ${role.notifs} , so how can i access the outer object "role" from the inner loop.
i got this error Neither BindingResult nor plain target object for bean name 'role' available as request attribute

thymeleaf passing a parameter from a form to a controller using a post

Im making an app where i have users and some of them have a role Mentor. Users can choose a mentor, who will in time add a personal program and food regime for the user. So far I am printing all the users, having the Mentor role in an html file, but i cant seem to pass the parameter (the current userID) in the post method to the controller.
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import javax.persistence.*;
#Entity
#Table(name = "users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(nullable = false, unique = true, length = 45)
private String email;
#Column(nullable = false, unique = true, length = 45)
private String username;
#Column(nullable = false, length = 64)
private String password;
#Column(name = "first_name", nullable = false, length = 20)
private String firstName;
#Column(name = "last_name", nullable = false, length = 20)
private String lastName;
#Column(name = "age", nullable = false, length = 20)
private int age;
#Column(name = "sex")
private String sex;
#Column(name = "mentor_id", nullable = true)
private Long mentorid;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name="account_id")
private accountInfo accountinfo;
public User() {}
#OneToMany(mappedBy="user")
private List<Blog> blogs= new ArrayList<Blog>();
#ManyToOne(optional = false,fetch = FetchType.LAZY)
#JoinColumn(name="role_id")
private UserRole role;
#OneToOne(mappedBy = "user")
private PersonalProgram personalprogram;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public accountInfo getAccountinfo() {
return accountinfo;
}
public void setAccountinfo(accountInfo accountinfo) {
this.accountinfo = accountinfo;
}
public List<Blog> getBlogs() {
return blogs;
}
public void setBlogs(List<Blog> blogs) {
this.blogs = blogs;
}
public UserRole getRole() {
return role;
}
public void setRole(UserRole role) {
this.role = role;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Optional<Long> getMentorid() {
return Optional.ofNullable(mentorid);
}
public void setMentorid(Long mentorid) {
this.mentorid = mentorid;
}
public PersonalProgram getPersonalprogram() {
return personalprogram;
}
public void setPersonalprogram(PersonalProgram personalprogram) {
this.personalprogram = personalprogram;
}
}
this is my user class
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>List of Trainers</title>
<link rel="stylesheet" type="text/css" href="/webjars/bootstrap/css/bootstrap.min.css" />
<script type="text/javascript" src="/webjars/jquery/jquery.min.js"></script>
<script type="text/javascript" src="/webjars/bootstrap/js/bootstrap.min.js"></script>
<script>
function getUser(userid) {
$.ajax({
url: "/trainers/choose?userId="+userid,
type: "get",
});
}
</script>
</head>
<body>
<div class="container text-center">
<div>
<h1>List of Trainers</h1>
</div>
<div>
<table class="table table-striped table-bordered">
<thead class="thead-dark">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Age</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tbody>
<tr th:each="user,index: ${listUsers}"> ///i print each user from the list User
<td th:text="${user.firstName}">First Name</td>
<td th:text="${user.lastName}">Last Name</td>
<td th:text="${user.age}">Age</td>
<td th:text="${user.email}">Email</td>
<td>
<form th:action="#{/trainers/choose}" th:object="${user}" method="post"> //Im trying to pass the id of the user on this row
<input type="hidden" th:field="*{id}" />
<button type="submit">Choose</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
and this is my html
and i guess the controllers handler about the post Method going to look something like this
#RequestMapping(value="trainers/choose", method = RequestMethod.POST)
public String processTrainersChoose (#RequestParam Long mentorid) {
and the get method for visualising the html page is
#GetMapping("/trainers")
public String listTrainers(Model model) {
List<User> listUsers = userRepo.findAllByRole(userRoleRepo.findByName("ROLE_MENTOR"));
model.addAttribute("listUsers", listUsers);
model.addAttribute("user", new User());
return "trainers";
}
```

Thymeleaf #sets.contains() always returning false despite usage according to documentation

Preface
I have a spring boot application with a User entity with a set of Role.
On the edit user template, I am displaying the user's roles with a <select>multiple. When rending the view of a existing User with its set of Role, I am trying to only mark as selected the roles within the set.
Thymeleaf provides two tools for this:
th:selected: Which expects a boolean value (true being selected)
#sets: Which provides a handful of useful methods similar to java.util.Set, the one being used in this case is contains().
The problem
When adding to the model a found User and all the possibles Role in the form of a HashSet, using #sets.contains() always return false when using the found user's roles and all the roles as parameters, therefore not selecting the user's roles when loading the form.
If I use the notation th:selected="${{user.roles}}" notation all the options are selected (even those the user does not posses).
The Code
User
public class User
{
private Long id;
private String username;
private String password;
private String passwordConfirm;
private Set<Role> roles;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
#Transient
public String getPasswordConfirm()
{
return passwordConfirm;
}
public void setPasswordConfirm(String passwordConfirm)
{
this.passwordConfirm = passwordConfirm;
}
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "users_role", joinColumns = #JoinColumn(name = "users_id"), inverseJoinColumns = #JoinColumn(name = "role_id"))
public Set<Role> getRoles()
{
return roles;
}
public void setRoles(Set<Role> roles)
{
this.roles = roles;
}
}
Role
public class Role
{
private Long id;
private String name;
private Set<User> users;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
#ManyToMany(mappedBy = "roles")
public Set<User> getUsers()
{
return users;
}
public void setUsers(Set<User> users)
{
this.users = users;
}
}
Controller
#Controller
#RequestMapping("/admin")
public class AdminController
{
#Autowired
UserService userService;
#Autowired
RoleService roleService;
#RequestMapping("/user/edit/{id}")
public String editUser(Model model, #PathVariable("id") long id)
{
User user = userService.findByUserId(id);
HashSet<Role> foundRoles = roleService.getAllRoles();
model.addAttribute("user", user);
model.addAttribute("userRoles", foundRoles);
return "admin/adminUserDetail";
}
}
The form
<form role="form" th:action="#{/registration}" method="POST"
th:object="${user}">
<div th:if="${#fields.hasErrors('*')}">
<div class="alert alert-danger" role="alert">
<h3 class="alert-heading">It seems we have a couple problems with your input</h3>
<li th:each="err : ${#fields.errors('*')}" th:text="${err}"></li>
</div>
</div>
<div class="form-group">
<label>Username: </label> <input class="form-control" type="text" th:field="${user.username}"
placeholder="Username" name="username"/>
<label>Password: </label> <input class="form-control" type="password" th:field="${user.password}"
placeholder="Password" name="password"/>
<label>Password Confirm: </label> <input type="password"
th:field="${user.passwordConfirm}" class="form-control"
placeholder="Password Confirm"/>
<select class="form-control" multiple="multiple">
<option th:each="role : ${userRoles}"
th:value="${role.id}"
th:selected="${#sets.contains(user.roles, role)}"
th:text="${role.name}">Role name
</option>
</select>
<button type="submit" class="btn btn-success">Update</button>
</div>
</form>
When using a Set the object in there must implement both hashCode and equals as that is used to determine if an object is already in the Set. Unless it is a SortedSet which uses either a Comparator or the natural order expressed through your object implementing Comparable.
As you don't do either of those using contains will simply always return false even for a seemingly same Role instance. Because according to the contract they aren't.
To fix implement the equals and hashCode method in your User and Role object.
public class Role {
public int hashCode() {
return Objects.hash(this.name);
}
public boolean equals(Object o) {
if (o == this) { return true; }
if (o == null || !(o instanceof Role) ) { return false; }
return Objects.equals(this.name, ((Role) o).name);
}
}
Something along those lines should do the trick.

Can't save many-to-many relations by form in JSP

The Context
I have a simple workshop application with three entities - Job, Employee and Customer. I am trying to create web interface which will add new Job in this case. Job has many to many relations with Employee and Customer. In Job entity there are lists of Employee and Customer as well.
The Problem
When I try to post my request with new Job through HTTP I get Bad Request 400 with description:
The server cannot or will not process the request due to something
that is perceived to be a client error (e.g., malformed request
syntax, invalid request message framing, or deceptive request
routing).
I don't know where excactly is bug.
Forms for adding Customer and Employee work fine.
The Code
Entities:
Employee
#Component
#Entity
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Pattern (regexp="[a-zA-Z]+")
#NotEmpty
private String employeeName;
#Pattern (regexp="[a-zA-Z]+")
#NotEmpty
private String employeeSurname;
#ManyToMany(mappedBy = "employeeList")
private List<Job> jobList;
public Employee() {
}
public Employee(int id, String employeeName, String employeeSurname) {
this.id = id;
this.employeeName = employeeName;
this.employeeSurname = employeeSurname;
}
public Employee(String employeeName, String employeeSurname) {
this.employeeName = employeeName;
this.employeeSurname = employeeSurname;
}
public List<Job> getJobList() {
return jobList;
}
public void setJobList(List<Job> jobList) {
this.jobList = jobList;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public String getEmployeeSurname() {
return employeeSurname;
}
public void setEmployeeSurname(String employeeSurname) {
this.employeeSurname = employeeSurname;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}}
Customer
#Component
#Entity
public class Customer {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Pattern(regexp="[a-zA-Z]+")
#NotEmpty
private String CustomerName;
#Pattern (regexp="[a-zA-Z]+")
#NotEmpty
private String CustomerSurname;
#Pattern (regexp = "\\w+")
#NotEmpty
private String car;
private int phonenumber;
#ManyToMany(mappedBy = "customerList")
private List<Job> jobList;
public Customer(String customerName, String customerSurname, String car, int phonenumber) {
CustomerName = customerName;
CustomerSurname = customerSurname;
this.car = car;
this.phonenumber = phonenumber;
}
public Customer(int id, String customerName, String customerSurname, String car, int phonenumber) {
this.id=id;
CustomerName = customerName;
CustomerSurname = customerSurname;
this.car = car;
this.phonenumber = phonenumber;
}
public Customer() {
}
public List<Job> getJobList() {
return jobList;
}
public void setJobList(List<Job> jobList) {
this.jobList = jobList;
}
public String getCustomerName() {
return CustomerName;
}
public void setCustomerName(String customerName) {
CustomerName = customerName;
}
public String getCustomerSurname() {
return CustomerSurname;
}
public void setCustomerSurname(String customerSurname) {
CustomerSurname = customerSurname;
}
public int getPhonenumber() {
return phonenumber;
}
public void setPhonenumber(int phonenumber) {
this.phonenumber = phonenumber;
}
public String getCar() {
return car;
}
public void setCar(String car) {
this.car = car;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}}
Job
#Component
#Entity
public class Job {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#NotEmpty
#Pattern(regexp="[a-zA-Z]+")
private String jobName;
#ManyToMany(fetch = FetchType.EAGER)
private List<Employee> employeeList;
#LazyCollection(LazyCollectionOption.FALSE)
#ManyToMany
private List<Customer> customerList;
public Job() {
}
public Job(String jobName, List<Employee> employeeList, List<Customer> customerList) {
this.jobName = jobName;
this.employeeList = employeeList;
this.customerList = customerList;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
public List<Employee> getEmployeeList() {
return employeeList;
}
public void setEmployeeList(List<Employee> employeeList) {
this.employeeList = employeeList;
}
public List<Customer> getCustomerList() {
return customerList;
}
public void setCustomerList(List<Customer> customerList) {
this.customerList = customerList;
}}
DaoImpl
JobDaoImpl
#Repository
public class JobDaoImpl implements JobDao {
#PersistenceContext
EntityManager entityManager;
#Override
public List<Job> findAllJobs() {
return entityManager.createQuery("select j from Job j order by j.id", Job.class)
.getResultList();
}
#Override
public Job addJob(Job job) {
entityManager.persist(job);
entityManager.flush();
entityManager.refresh(job);
return job;
}}
Service
JobService
#Service
#Transactional
public class JobService {
private JobDao jobDao;
public List<Job> findAllJobs(){
return jobDao.findAllJobs();
}
public Job addNewJob(Job job){return jobDao.addJob(job);}
public JobService(JobDao jobDao) {
this.jobDao = jobDao;
}
}
Controller
JobController
#Controller
public class JobController {
JobService jobService;
EmployeeService employeeService;
CustomerService customerService;
public JobController(JobService jobService, EmployeeService employeeService, CustomerService customerService) {
this.jobService = jobService;
this.employeeService = employeeService;
this.customerService = customerService;
}
//JOB INDEX
#RequestMapping("job-index.html")
public ModelAndView getJobIndex() {
ModelAndView modelAndView = new ModelAndView("jobViews/jobIndex");
return modelAndView;
}
//SHOW EMPLOYEES
#RequestMapping("show-jobs.html")
public ModelAndView getAllJobs() {
ModelAndView modelAndView = new ModelAndView("jobViews/jobs");
modelAndView.addObject("jobs", jobService.findAllJobs());
return modelAndView;
}
//ADD NEW JOB GET METHOD
#GetMapping(value = "add-job.html")
public ModelAndView addNewJob(){
return new ModelAndView("jobViews/addJob","job", new Job());
}
//ADD NEW JOB POST METHOD
#PostMapping(value = "add-job.html")
public ModelAndView addNewJob(#ModelAttribute Job job){
return new ModelAndView("jobViews/addJobConfirmation","job",job);
}
#ModelAttribute("employeeInit")
public List<Employee> initializeEmployees() {
return employeeService.findAllEmployee();
}
#ModelAttribute("customerInit")
public List<Customer> initializeCustomer(){ return customerService.findAllCustomer();}}
JSP Views
addJob.jsp
<f:form method="post" modelAttribute="job">
<p>Job name:<f:input path="jobName"/></p>
<f:hidden path="id"/>
<f:select path="employeeList" multiple="true">
<f:options items="${employeeInit}" itemLabel="employeeSurname" itemValue="id"></f:options>
</f:select>
<f:select path="customerList" multiple="true">
<f:options items="${customerInit}" itemLabel="customerSurname" itemValue="id"></f:options>
</f:select>
<button type="submit">Add</button>

JSP, show results from two tables in for each

In JSP I have simple foreach, which should display the information from two tables. First table "Organizations" as "country" parameter keeps id of country as a foreign key to another table "Countries".
How can I show country name in this foreach, which keeps in “Organizations" as id of country?
<c:forEach items=“${organizations}" var=“organization">
<c:url var="edit" value="/edit/${organization.id}" />
<c:url var="remove" value="/remove/${organization.id}" />
<tr>
<td><c:out value="${organization.name}" /></td>
<td><c:out value="${organization.country}" /></td> // In this line
<td><c:out value="${organization.address}" /></td>
<td><c:out value="${organization.phone}" /></td>
<td><c:out value="${organization.market_cap}" /></td>
<td valign = "top">Edit</td>
<td valign = "top">Remove</td>
</tr>
</c:forEach>
Tables:
CREATE TABLE IF NOT EXISTS Organization (id int auto_increment , name varchar(255), country int, address varchar(255), phone varchar(255)primary key(id), foreign key (country) references public.country(id_country));
CREATE TABLE IF NOT EXISTS Country (id_country int auto_increment , name varchar(255), primary key(id_country));
Model, Organization:
import javax.persistence.*;
#Entity
public class Organization {
#Id
#GeneratedValue
private Integer id;
private String name;
private Integer country;
private String address;
private String phone;
private Long market_cap;
public Organization(Integer id, String name, Integer country, String address, String phone, Long market_cap) {
this.id = id;
this.name = name;
this.country = country;
this.address = address;
this.phone = phone;
this.market_cap = market_cap;
}
public Organization() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCountry() {
return country;
}
public void setCountry(Integer country) {
this.country = country;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Long getMarket_cap() {
return market_cap;
}
public void setMarketCap(Long market_cap) {
this.market_cap = market_cap;
}
}
Model, Country:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
#Entity
public class Country {
#Id
#GeneratedValue
private Integer id_country;
private String name;
private String isocode;
public Country() {
}
public Country(Integer id_country, String name, String isocode) {
this.id_country = id_country;
this.name = name;
this.isocode = isocode;
}
public Integer getId_country() {
return id_country;
}
public void setId_country(Integer id_country) {
this.id_country = id_country;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIsocode() {
return isocode;
}
public void setIsocode(String isocode) {
this.isocode = isocode;
}
}
Controller:
#Controller
#RequestMapping("/")
public class HomeController {
private final OrganizationService organizationService;
private final CountryService countryService;
#Autowired
public HomeController(final OrganizationService organizationService, final CountryService countryService) {
this.organizationService = organizationService;
this.countryService = countryService;
}
#RequestMapping(value="add", method=RequestMethod.GET)
public ModelAndView addOrganization() {
ModelAndView modelAndView = new ModelAndView("add");
Organization organization = new Organization();
modelAndView.addObject("organization", organization);
List<Country> countries = countryService.listOfCountries();
modelAndView.addObject("countries", countries);
return modelAndView;
}
#RequestMapping(value="add", method=RequestMethod.POST)
public ModelAndView addingConfirm(Organization organization)
{
ModelAndView modelAndView = new ModelAndView("confirm");
organizationService.addOrganization(organization);
String message = "Organization was successfully added.";
modelAndView.addObject("message", message);
return modelAndView;
}
#RequestMapping(method = RequestMethod.GET)
public ModelAndView list() {
ModelAndView modelAndView = new ModelAndView("index");
List<Organization> organizations = organizationService.listOfOrganizations();
modelAndView.addObject("organizations", organizations);
return modelAndView;
}
#RequestMapping(value="/edit/{id}", method=RequestMethod.GET)
public ModelAndView editOrganization(#PathVariable Integer id) {
ModelAndView modelAndView = new ModelAndView("edit");
Organization organization = organizationService.getOrganization(id);
modelAndView.addObject("organization", organization);
List<Country> countries = countryService.listOfCountries();
modelAndView.addObject("countries", countries);
return modelAndView;
}
#RequestMapping(value="/edit/{id}", method=RequestMethod.POST)
public ModelAndView editConfirm(#ModelAttribute Organization organization, #PathVariable Integer id) {
ModelAndView modelAndView = new ModelAndView("confirm");
organizationService.editOrganization(organization);
String message = "Organization was successfully edited.";
modelAndView.addObject("message", message);
return modelAndView;
}
#RequestMapping(value="/remove/{id}", method=RequestMethod.GET)
public ModelAndView removeOrganization(#PathVariable Integer id) {
ModelAndView modelAndView = new ModelAndView("confirm");
organizationService.removeOrganization(id);
String message = "Organization was successfully deleted.";
modelAndView.addObject("message", message);
return modelAndView;
}
}
Your model is inadequate for that kind operation. What you need to do is:
Your model must change:
import javax.persistence.*;
#Entity
public class Organization {
#Id
#GeneratedValue
private Integer id;
private String name;
//This will load automatically when you load your Organization entity.
#OneToOne(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
#JoinColumn(name="country")
private Country country;
private String address;
private String phone;
private Long market_cap;
public Organization(Integer id, String name, Country country, String address, String phone, Long market_cap) {
this.id = id;
this.name = name;
this.country = country;
this.address = address;
this.phone = phone;
this.market_cap = market_cap;
}
public Organization() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Long getMarket_cap() {
return market_cap;
}
public void setMarketCap(Long market_cap) {
this.market_cap = market_cap;
}
}
and in you view in that case jsp:
<c:forEach items=“${organizations}" var=“organization">
<c:url var="edit" value="/edit/${organization.id}" />
<c:url var="remove" value="/remove/${organization.id}" />
<tr>
<td><c:out value="${organization.name}" /></td>
<td><c:out value="${organization.country.name}" /></td> //Should do the trick
<td><c:out value="${organization.address}" /></td>
<td><c:out value="${organization.phone}" /></td>
<td><c:out value="${organization.market_cap}" /></td>
<td valign = "top">Edit</td>
<td valign = "top">Remove</td>
</tr>
</c:forEach>

Resources