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

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";
}
```

Related

Couldn't join two tables on Spring boot

I am a beginner of spring boot application. I want to join the course table and the student table together. What I tried so far I attached code below. I didn't get any errors. When the student page is loaded I show course id only I need to display the name instead of the id. I attached the screenshot image below.
Above screenshot image only displayed the course id I need to display the course name.
Student Controller
#RequestMapping(value = "/student", method = RequestMethod.GET)
public String viewStudentPage(Model model) {
List<Student> liststudent = services.listAll();
model.addAttribute("liststudent", liststudent);
System.out.print("Get / ");
return "Student";
}
I made the relation the below. What I tried so far now.
Course.java
#Entity
public class Course {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
private String coursename;
private int duration;
#ManyToOne
private Student student;
public Course()
{
}
public Course(Long id, String coursename, int duration) {
this.id = id;
this.coursename = coursename;
this.duration = duration;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCoursename() {
return coursename;
}
public void setCoursename(String coursename) {
this.coursename = coursename;
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
#Override
public String toString() {
return "Course [id=" + id + ", coursename=" + coursename + ", duration=" + duration + "]";
}
}
Student.java
#Entity
#Table(name="student")
public class Student {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
private String stname;
private int course;
private int fee;
#OneToMany(mappedBy = "course")
private List<Student> student;
public Student() {
}
public Student(Long id, String stname, int course, int fee) {
this.id = id;
this.stname = stname;
this.course = course;
this.fee = fee;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getStname() {
return stname;
}
public void setStname(String stname) {
this.stname = stname;
}
public int getCourse() {
return course;
}
public void setCourse(int course) {
this.course = course;
}
public int getFee() {
return fee;
}
public void setFee(int fee) {
this.fee = fee;
}
#Override
public String toString() {
return "Student [id=" + id + ", stname=" + stname + ", course=" + course + ", fee=" + fee + "]";
}
}
StudentRepository
#Repository
public interface StudentRepository extends JpaRepository<Student, Long>{ }
Student.html
<table class="table">
<thead class="thead-dark">
<tr>
<th>Student ID</th>
<th>Student Name</th>
<th>Course Name</th>
<th>Fee</th>
<th>edit</th>
<th>delete</th>
</tr>
</thead>
<tbody>
<tr th:each="student : ${liststudent}">
<td th:text="${student.id}">Student ID</td>
<td th:text="${student.stname}">Student Name</td>
<td th:text="${student.course}">Course</td>
<td th:text="${student.fee}">Fee</td>
<td>
<a th:href="#{'/Student/edit/' + ${student.id}}">Edit</a>
</td>
<td>
<a th:href="#{'/Student/delete/' + ${student.id}}">Delete</a>
</td>
</tr>
</tbody>
</table>
Custom Code i wrote it to Join
#Repository
public interface StudentRepository extends JpaRepository<Student, Long>{
#Query(value="select student.id, student.stname, course.coursename from student Inner JOIN course ON student.course= course.id", nativeQuery=true)
List<Object[]> findStudent();
}
You have to add a custom query to get the course name. Your listAll() return all student object without course, the payload doesn't have any variable like name and you have course id in your entity that's why ID appearing in your UI.
Your student object have course objects also you can get like below.
you have the wrong relationship on your entity correct as below.
It should come under ManyToMany relationship because one user have many courses and one course belong to many student anyway you started as oneToMany then follow as below.
within Student Entity.
#OneToMany(fetch = FetchType.LAZY,
cascade = CascadeType.ALL,mappedBy = "student")
private List<Course> course;
within Course entity
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "id", nullable = false)
private Student student;
then try you access the course object as below.
th:field="*{student.course.name}"
if you want to try a custom query then try to as below.
#Query(value="select s.id, s.name, c.name from Student s left JOIN Course c on student.course_id= c.id", nativeQuery=true)
List<Object[]> findStudent();

Changes not persisted in database in a Spring Boot application using Spring JPA

I have a Spring Boot application that needs adds a post to a feed list. A post is written by a user and consists of a content and several attachments. The database has 3 tables: post, attachment and user.
The main class of the application is:
#SpringBootApplication
public class SocialMediaApplication {
public static void main(String[] args) {
SpringApplication.run(SocialMediaApplication.class, args);
}
}
The entities are the following:
Post.java
#Entity
public class Post implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(nullable = false)
private String content;
#ManyToOne
#JoinColumn(name = "user_id")
private User user;
#Column(nullable = false)
private Timestamp createdAt;
#Column
private String location;
#OneToMany(mappedBy = "post", cascade = CascadeType.ALL)
private List<Attachment> attachmentList;
#OneToMany(mappedBy = "post", cascade = CascadeType.ALL)
private List<Rating> ratingList;
public Post() {
}
public Post(String content, User user, Timestamp createdAt, String location, List<Attachment> attachmentList, List<Rating> ratingList) {
super();
this.content = content;
this.user = user;
this.createdAt = createdAt;
this.location = location;
this.attachmentList = attachmentList;
this.ratingList = ratingList;
}
// ...
}
Attachment.java
#Entity
public class Attachment implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Lob
#Column(length = 100_000, nullable = false)
private byte[] content;
#ManyToOne
#JoinColumn(name = "post_id")
private Post post;
public Attachment() {
}
public Attachment(byte[] content, Post post) {
super();
this.content = content;
this.post = post;
}
// ...
}
User.java
#Entity
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
private Long id;
#Column(nullable = false)
private String firstName;
#Column(nullable = false)
private String lastName;
#Column(nullable = false)
private Date dateOfBirth;
#Column(nullable = false)
private String credential;
#Column(nullable = false)
private String password;
#Column
private String location;
#Lob
#Column(length = 100_000)
private byte[] photo;
#Column
private String motto;
public User() {
}
public User(String firstName, String lastName, Date dateOfBirth, String credential, String password,
String location, byte[] photo, String motto) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.dateOfBirth = dateOfBirth;
this.credential = credential;
this.password = password;
this.location = location;
this.photo = photo;
this.motto = motto;
}
// ...
}
All repositories extend CrudRepository and are annotated with #Transactional:
PostRepository.java
#Transactional
public interface PostRepository extends CrudRepository<Post, Long> {
}
AttachmentRepository.java
#Transactional
public interface AttachmentRepository extends CrudRepository<Attachment, Long> {
}
UserRepository.java
#Transactional
public interface UserRepository extends CrudRepository<User, Long> {
}
The controller that should add a post to the feed is the following:
#Controller
#RequestMapping("/post")
public class PostController {
#Autowired
PostRepository postRepository;
#GetMapping("/add")
public String greetingForm(Model model) {
model.addAttribute("post", new Post());
return "addPost";
}
#PostMapping("/add")
public String addPost(#ModelAttribute Post post, #RequestParam("attachment") MultipartFile uploadingFile) throws IOException {
User user = new User();
user.setId(1L);
post.setUser(user);
post.setCreatedAt(Timestamp.valueOf(LocalDateTime.now()));
List<Attachment> attachmentList = new ArrayList<>();
Attachment attachment = new Attachment();
attachment.setContent(uploadingFile.getBytes());
attachment.setPost(post);
attachmentList.add(attachment);
post.setAttachmentList(attachmentList);
List<Rating> ratingList = new ArrayList<>();
post.setRatingList(ratingList);
postRepository.save(post);
return "allPosts";
}
}
The addPost.html page has the following content:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Add Post</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Add Post</h1>
<form action="#" th:action="#{/post/add}" th:object="${post}" method="post" enctype="multipart/form-data">
<table border="0">
<tr>
<td>Content</td>
<td><textarea id="content" th:field="*{content}" rows="5" cols="50"></textarea></td>
</tr>
<tr>
<td>Location</td>
<td><input type="text" id="location" th:field="*{location}"/></td>
</tr>
<tr>
<td>Attachment</td>
<td><input type="file" id="attachment" name="attachment"/></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Submit" />
<input type="reset" value="Reset" />
</td>
</tr>
</table>
</form>
</body>
</html>
The application.properties file has the following content:
spring.datasource.url=jdbc:mysql://localhost:3306/****?useSSL=false
spring.datasource.username=root
spring.datasource.password=****
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.id.new_generator_mappings=false
spring.jpa.show-sql=true
spring.thymeleaf.cache=false
spring.thymeleaf.enabled=true
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
However, when I press the submit button, nothing is persisted into the database, although the queries are being displayed in the console:
Hibernate: insert into post (content, created_at, location, user_id) values (?, ?, ?, ?)
Hibernate: insert into attachment (content, post_id) values (?, ?)
What could be the cause?

Get list within a list using Thymeleaf

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>

Selection of multiple columns unsing spring data JPA and JPQL

I am trying to select two columns which are in two separate tables. One table is users and other one is privillages. I need to fetch username from users and pname from privillages. My model classes are like follows,
#Entity
#Table(name = "users")
public class Users implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
public String username;
public String password;
public Integer privid;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "pid")
private Collection<Privillages> priviJoin;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "username")
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
#Column(name = "password")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Column(name = "privid")
public Integer getPrivid() {
return privid;
}
public void setPrivid(Integer privid) {
this.privid = privid;
}
public Collection<Privillages> getPriviJoin() {
return priviJoin;
}
public void setPriviJoin(Privillages priviJoin) {
this.priviJoin = (Collection<Privillages>) priviJoin;
}
public Users() {
}
#Override
public String toString() {
return String.format("Users[id=%d, username='%s', password='%s']", id,
username, password);
}
}
And my Privillages class is,
#Entity
#Table(name = "privillages")
public class Privillages implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public Integer id;
public String pname;
#ManyToOne(optional = false)
#JoinColumn(name = "pid", referencedColumnName = "privid")
public Users pid;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "pname")
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
#Column(name = "pid")
public Users getPid() {
return pid;
}
public void setPid(Users pid) {
this.pid = pid;
}
public Privillages(){
}
}
And my Users repository is,
public interface UsersRepository extends CrudRepository<Users, Integer>
{
#Query("select u from Users ug join ug.priviJoin u")
List<Users> findByUsername();
}
And My Privillage repository is:
public interface PrivillagesRepository extends CrudRepository<Privillages,
Integer> {
}
My controller file is:
#RequestMapping(value = "/joinResult", method = RequestMethod.GET)
public ModelAndView joinResultShow(Model model)
{
List<Privillages> privillages = (List<Privillages>)privillagesRepo.findAll();
model.addAttribute("joinData",privillages);
ModelAndView viewObj = new ModelAndView("fleethome");
return viewObj;
}
And displaying like:
<table>
<tr th:each="message : ${joinData}">
<td th:text="${message.pname}"></td>
<td th:text="${message.pid.username}"></td>
</tr>
</table>
And getting error like:
There was an unexpected error (type=Internal Server Error, status=500).
No message available
Stacktrace is:
java.lang.NullPointerException: null
at
com.central.controller.WebController.joinResultShow(WebController.java:58) ~
[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~
[na:1.8.0_141]
at sun.reflect.NativeMethodAccessorImpl.invoke
(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_141]
at sun.reflect.DelegatingMethodAccessorImpl.
invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_141]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_141]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke
(InvocableHandlerMethod.java:205) ~[spring-web-
4.3.11.RELEASE.jar:4.3.11.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.
invokeForRequest(InvocableHandlerMethod.java:133) ~[spring-web-
4.3.11.RELEASE.jar:4.3.11.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.
ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.
java:97) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.
RequestMappingHandlerAdapter.invokeHandlerMethod
(RequestMappingHandlerAdapter .java:827)
~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
at org.springframework.web.servlet.mvc.method.
annotation.RequestMappingHandlerAdapter.handleInternal
(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-
4.3.11.RELEASE.jar:4.3.11.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.
handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-
4.3.11.RELEASE.jar:4.3.11.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.
doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-
4.3.11.RELEASE.jar:4.3.11.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService
(DispatcherServlet.java:901) ~[spring-webmvc-
4.3.11.RELEASE.jar:4.3.11.RELEASE]
I need to retrieve username from users and pname column from privillages. How should I change my code?
First of all, you should create privillages repository:
public interface PrivillagesRepository extends CrudRepository<Privillages, Integer> {
}
Then you can do find all privillages in your controller:
List<Privillages> privillages = privillages.findAll();
model.addAttribute("joinData",privillages);
After that, change your template:
<table>
<tr th:each="message : ${joinData}">
<td th:text="${message.pname}"></td>
<td th:text="${message.pid.username}"></td>
</tr>
</table>
As you can see, to print username, you need to use nested field "pid" (Users class)
I just explored the context that, Use the same repository as the Userrepository along with the JPQL query. And modify the view file according to that for displaying username with using the pid from Privillages Model class. I am adding the code need to modify with certain changes.
My controller file is,
UsersRepository userRepo;
#RequestMapping(value = "/joinResult", method = RequestMethod.GET)
public ModelAndView joinResultShow(Model model)
{
List<Users> use = (List<Users>) userRepo.findByUsername();
model.addAttribute("joinData",use);
ModelAndView viewObj = new ModelAndView("fleethome");
return viewObj;
}
And the repository ,
public interface UsersRepository extends CrudRepository<Users, Integer>
{
Users findByUsernameAndPassword(String username,String password);
#Query("select u from Users ug join ug.priviJoin u")
List<Users> findByUsername();
}
And My Privillage repository,
public interface PrivillagesRepository extends CrudRepository<Privillages,
Integer> {
}
And modify the View file with,
<table>
<th> Username </th>
<th> Privillage Name </th>
<tr th:each="message : ${joinData}">
<td th:text="${message.pid.username}"></td>
<td th:text="${message.pname}"></td>
</tr>
</table>

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