Couldn't join two tables on Spring boot - spring

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();

Related

How can I fetch data from 2 tables using HQL having one to many association with each other?

I have 2 tables in my database, city and hotel_details. Primary key of city is foreign key in hotel_details and associated with one to many association. I want to fetch data(status,registration,etc..) from hotel_details based on city_id and hotel_name by calling getAvailabilityStatus from my controller. Following is my code :
City Entity class
#Entity
#Table(name="city")
public class City {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private int id;
#Column(name="city_name")
private String cityName;
#OneToMany(mappedBy="city",
cascade= {CascadeType.PERSIST, CascadeType.MERGE,
CascadeType.DETACH, CascadeType.REFRESH})
private List<HotelDetails> hotelDetails;
public City() {
}
public List<HotelDetails> getHotelDetails() {
return hotelDetails;
}
public void setHotelDetails(List<HotelDetails> hotelDetails) {
this.hotelDetails = hotelDetails;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
#Override
public String toString() {
return "City [id=" + id + ", cityName=" + cityName + "]";
}
}
2.HotelDetails Entity class
#Entity
#Table(name="hotel_details")
public class HotelDetails {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private int id;
#ManyToOne(cascade= {CascadeType.PERSIST, CascadeType.MERGE,
CascadeType.DETACH, CascadeType.REFRESH})
#JoinColumn(name="city_id")
private City city;
#Column(name="hotel_name")
private String hotelName;
#Column(name="available_date")
#DateTimeFormat(pattern = "dd/MM/yyyy")
private Date availableDate;
#Column(name="price")
private int price;
#Column(name="gst")
private int gst;
#Column(name="status")
private int status;
#Column(name="room_type")
private String roomType;
public HotelDetails() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
public String getHotelName() {
return hotelName;
}
public void setHotelName(String hotelName) {
this.hotelName = hotelName;
}
public Date getAvailableDate() {
return availableDate;
}
public void setAvailableDate(Date availableDate) {
this.availableDate = availableDate;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getGst() {
return gst;
}
public void setGst(int gst) {
this.gst = gst;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getRoomType() {
return roomType;
}
public void setRoomType(String roomType) {
this.roomType = roomType;
}
#Override
public String toString() {
return "HotelDetails [id=" + id + ", hotelName=" + hotelName + ", availableDate=" + availableDate + ", price="
+ price + ", gst=" + gst + ", status=" + status + ", roomType=" + roomType + "]";
}
}
3.HotelDAOImpl
#Component
#Repository
public class HotelDetailsDAOImpl implements HotelDetailsDAO {
#Autowired
private SessionFactory sessionFactory;
#Override
#Transactional
public Set<String> getHotels() {
Session currentSession = sessionFactory.getCurrentSession();
Query theQuery2 = currentSession.createQuery("Select h.hotelName from HotelDetails h");
List<String> listHotels = theQuery2.list();
Set<String> hotels = new HashSet<String>(listHotels);
return hotels;
}
#Override
#Transactional
public List<City> getAvailabilityStatus(int cityID, String hotelName, String cityName) {
Session currentSession = sessionFactory.getCurrentSession();
Query theQuery4 = currentSession.createQuery("...");
//theQuery4.setParameter("hotelName", hotelName);
//List<City> cities = theQuery4.list();
return cities;
}
}
String jpql = "select c from City c join c.hotelDetails h where h.hotelName = :hotelName";
or
String jpql = "select c from HotelDetails h join h.city c where h.hotelName = :hotelName";
and then
Query theQuery4 = currentSession.createQuery(jpql);
theQuery4.setParameter("hotelName", hotelName);
List<City> cities = theQuery4.list();
This is just an example, but once you have defined the join and the entity aliases correctly, you can refer to entity attributes in the WHERE clause any way you prefer.
For example:
jpql += " AND c.id=:id AND h.price<:price AND h.availableDate BETWEEN :start AND :end";
same for the select clause, you can use all the combinations of:
"select c.cityName, h.status, ..."
"select c, h from ..."
Check the Hibernate ORM query for many examples of how you can use JPQL/HQL.

createalias in hibernate is joining parent table two times

I have bidirectional one to many between department and employees.ie one department can have multiple employees.
I want to join department and employees using hibernate criteria so for that i am using createalias method.
Criteria criteriaDepartment = session.createCriteria(DepartmentEntity.class);
criteriaDepartment.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
criteriaDepartment.createAlias("employeeEntity", "emp",JoinType.LEFT_OUTER_JOIN);
List<DepartmentEntity> list = criteriaDepartment.list();
However, hibernate joins department table with employees and then again with the department table.
Query generated by hibernate is as follows:
Hibernate: select this_.id as id1_1_2_, this_.name as name2_1_2_, emp1_.deptId as deptId7_2_4_, emp1_.id as id1_2_4_, emp1_.id as id1_2_0_, emp1_.address as address2_2_0_, emp1_.deptId as deptId7_2_0_, emp1_.password as password3_2_0_, emp1_.phoneno as phoneno4_2_0_, emp1_.type as type5_2_0_, emp1_.userid as userid6_2_0_, department4_.id as id1_1_1_, department4_.name as name2_1_1_ from Department4 this_ left outer join Userdetails4 emp1_ on this_.id=emp1_.deptId left outer join Department4 department4_ on emp1_.deptId=department4_.id
Why Department table is joining multiple times??? Is there any way to prevent this. I have to use some restrictions as well.
However when i use fetchmode it works fine but with this method i am not able to use aliases.
Department class:
#Entity
#Table(name = "Department4")
public class DepartmentEntity {
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE)
public int id;
public String name;
#OneToMany(mappedBy= "departmentEntity", cascade= CascadeType.ALL, orphanRemoval = true)
public Set<EmployeeEntity> employeeEntity = new HashSet<EmployeeEntity>();
public Set<EmployeeEntity> getEmployeeEntity() {
return employeeEntity;
}
public void setEmployeeEntity(Set<EmployeeEntity> employeeEntity) {
this.employeeEntity = employeeEntity;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "DepartmentEntity [id=" + id + ", name=" + name + ", employeeEntity=" + employeeEntity + "]";
}
}
Employee class
#Entity
#Table(name="Userdetails4")
public class EmployeeEntity {
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE)
private int id;
private String userid;
private String password;
private String address;
private long phoneno;
private String type;
#ManyToOne
#JoinColumn(name = "deptId")
private DepartmentEntity departmentEntity;
#OneToMany(mappedBy = "employeeEntity", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<AddressEntity> addressEntity = new HashSet<AddressEntity>();
public Set<AddressEntity> getAddressEntity() {
return addressEntity;
}
public void setAddressEntity(Set<AddressEntity> addressEntity) {
this.addressEntity = addressEntity;
}
public DepartmentEntity getDepartmentEntity() {
return departmentEntity;
}
public void setDepartmentEntity(DepartmentEntity departmentEntity) {
this.departmentEntity = departmentEntity;
}
public EmployeeEntity()
{}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public long getPhoneno() {
return phoneno;
}
public void setPhoneno(long phoneno) {
this.phoneno = phoneno;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
#Override
public String toString() {
return "EmployeeEntity [id=" + id + ", userid=" + userid + ", password=" + password + ", address=" + address
+ ", phoneno=" + phoneno + ", type=" + type + "]";
}
}
Hibernate version: 5.2.1
Thanks in advance.

Spring JPARepository querying many to many intersection table

I have 3 entity classes as follows (Example taken from https://hellokoding.com/jpa-many-to-many-extra-columns-relationship-mapping-example-with-spring-boot-maven-and-mysql/)
Book class
#Entity
public class Book{
private int id;
private String name;
private Set<BookPublisher> bookPublishers;
public Book() {
}
public Book(String name) {
this.name = name;
bookPublishers = new HashSet<>();
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#OneToMany(mappedBy = "book", cascade = CascadeType.ALL, orphanRemoval = true)
public Set<BookPublisher> getBookPublishers() {
return bookPublishers;
}
public void setBookPublishers(Set<BookPublisher> bookPublishers) {
this.bookPublishers = bookPublishers;
}
}
Publisher class
#Entity
public class Publisher {
private int id;
private String name;
private Set<BookPublisher> bookPublishers;
public Publisher(){
}
public Publisher(String name){
this.name = name;
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#OneToMany(mappedBy = "publisher")
public Set<BookPublisher> getBookPublishers() {
return bookPublishers;
}
public void setBookPublishers(Set<BookPublisher> bookPublishers) {
this.bookPublishers = bookPublishers;
}
}
Intersection Table
#Entity
#Table(name = "book_publisher")
public class BookPublisher implements Serializable{
private Book book;
private Publisher publisher;
private Date publishedDate;
#Id
#ManyToOne
#JoinColumn(name = "book_id")
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
#Id
#ManyToOne
#JoinColumn(name = "publisher_id")
public Publisher getPublisher() {
return publisher;
}
public void setPublisher(Publisher publisher) {
this.publisher = publisher;
}
#Column(name = "published_date")
public Date getPublishedDate() {
return publishedDate;
}
public void setPublishedDate(Date publishedDate) {
this.publishedDate = publishedDate;
}
}
I want to query 2 things,
Get list of books belonging to a particular publisher e.g. get all books associated with publisher 100
Get list of books not associated with a particular publisher e.g. get all books not associated with publisher 100
I want to achieve this using a simple JPARepository query if possible like findByXYZIn(...) etc.
Please let me know if querying a many to many relation is possible using JPA repository queries and if yes, whether I can do it directly or would it require any changes in the entity classes
In BookRepository
Get publisher's books
findBooksByBookPublishersPublisherId(Long publisherId)
Get books not published by publisher
findBooksByBookPublishersPublisherIdNot(Long publisherId)
IMHO Publication is much more apropriate name then BookPublisher in your case as Publisher by itself could be BookPublisher (a published that publishing books)
I'm not sure if you can make it just by method name. But you definitely can use JPA query. Something like this: "SELECT b FROM Book b JOIN b.bookPublishers bp JOIN bp.publisher p WHERE p.id = ?1". and with not equal for the second case
Well you can use named Queries to fulfill your requirements:
#Query("select b from Book b where b.publisher.idd = ?1")
Book findByPublisherId(int id);
#Query("select b from Book b where b.publisher.idd <> ?1")
Book findByDifferentPublisherId(int id);
Take a look at Using #Query Spring docs for further details.

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