I am using Java,Maven,Hibernate 3/JPA ,Eclipse to implement a PUT method for populating a Mysql db.
Here is my POJO
import static javax.persistence.GenerationType.IDENTITY;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.UniqueConstraint;
#Entity
#Table(name = "Person", catalog = "mydb", uniqueConstraints = {
#UniqueConstraint(columnNames = "Person"),})
public class Person implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String Name;
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id", unique = true, nullable = false)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "name", unique = true, nullable = false, length = 30)
public String getName() {
return flowName;
}
public void setName(String Name) {
this.Name = Name;
}
}
Here is my annotations class.
import javax.ws.rs.Consumes;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import com.google.gson.Gson;
import com.tracker.domain.Flow;
import com.tracker.persistence.HibernateUtil;
public class PersonService {
private Logger LOG = Logger.getLogger(TrackerService.class);
String JsonString = "{\"name\":\"John Doe\"}";
Gson gson = new Gson();
Person person = gson.fromJson(JsonString,Person.class);
#PUT
#Path("")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public void processandSaveJson(Person person) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
String Name = Person.getName();
person.setName(Name);
session.beginTransaction();
session.save(person);
session.getTransaction().commit();
}
}
Here is my Hibernate.Util.
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new AnnotationConfiguration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdown() {
// Close caches and connection pools
getSessionFactory().close();
}
}
Here is my SessionFactory Context Listener class
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import org.apache.log4j.Logger;
import org.hibernate.Session;
#WebListener
public class SessionFactoryListener implements ServletContextListener {
private Logger LOG = Logger.getLogger(SessionFactoryListener.class);
#Override
public void contextInitialized(ServletContextEvent arg0) {
if (LOG.isInfoEnabled()) {
LOG.info("\n\tInside contextInitialized()---\n");
}
Session session = HibernateUtil.getSessionFactory().openSession();
}
#Override
public void contextDestroyed(ServletContextEvent arg0) {
if (LOG.isInfoEnabled()) {
LOG.info("\n\tInside contextDestroyed()\n");
}
HibernateUtil.shutdown();
}
}
When I try to run this using Tomcat Server, i get the following error.
type Status report
message Method Not Allowed
description The specified HTTP method is not allowed for the requested resource.
I am very new to this. Kindly let me know what I am doing wrong. I trying to insert a
record into a mysql db using the above values. Kindly help me out.
Thanks,
Jack
as mentioned in the comments, you should supply your calling code along with the rest. but since you already mentioned that you're using a browser to make the request, it should be mentioned that most/no browsers support 'put' without using javadcript. what you are doing looks like a simple 'get'.
so the solution is to either use javascript in your form submission, or discard REST and have Urls that reflect the method (eg. /person/new/ and /person/{personId}
Related
I am building a SpringBoot API to learn the framework and I am facing two curious problems which probably are linked in some way.
First problem, when I try to test my code with my own Junit test class called EmployeeControllerTest, calling the method with http request returns the following error :
jakarta.servlet.ServletException: Request processing failed: java.util.NoSuchElementException: No value present
Second problem, when I perform those tests with Postman, the request /employees returning the list of employees works perfectly but the request /employee (with or without id added to the url), the API returns nothing.
In addition to this, calling the method from inside the code (in the run class) works great, I have every result I need.
Here are the code of every part involved. First the model class :
package com.openclassrooms.api.models;
import jakarta.persistence.*;
import lombok.Data;
#Data
#Entity
#Table(name = "employees")
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
private String mail;
private String password;
}
The repository class :
package com.openclassrooms.api.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.openclassrooms.api.models.Employee;
#Repository
public interface EmployeeRepository extends CrudRepository<Employee, Long> {
}
The service class :
package com.openclassrooms.api.service;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.openclassrooms.api.models.Employee;
import com.openclassrooms.api.repository.EmployeeRepository;
#Service
public class EmployeeService {
#Autowired
private EmployeeRepository employeeRepository;
public Optional<Employee> getEmployee(final Long id) {
System.out.println("getEmployee ok");
return employeeRepository.findById(id);
}
public Iterable<Employee> getEmployees() {
System.out.println("getEmployees ok");
return employeeRepository.findAll();
}
public void deleteEmployee(final Long id) {
employeeRepository.deleteById(id);
}
public Employee saveEmployee(Employee employee) {
Employee savedEmployee = employeeRepository.save(employee);
return savedEmployee;
}
}
and the controller class :
package com.openclassrooms.api.controller;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.openclassrooms.api.models.Employee;
import com.openclassrooms.api.service.EmployeeService;
#RestController
public class EmployeeController {
#Autowired
private EmployeeService employeeService;
// Read - Get all employees
// #return - An Iterable object of Employee full filled
#GetMapping("/employees")
public Iterable<Employee> getEmployees() {
Iterable<Employee> list = employeeService.getEmployees();
System.out.println(list);
return list;
}
#GetMapping("/employee/{id}")
public Employee getEmployee(#PathVariable("id") final Long id) {
Optional<Employee> emp = employeeService.getEmployee(id);
if (emp.isEmpty()) {
Employee employe = emp.get();
System.out.println(employe.getFirstName());
return employe;
} else {
System.out.println("ABSENT");
return null;
}
}
#GetMapping("/employee")
public Employee getEmployee() {
Optional<Employee> emp = employeeService.getEmployee(1L);
if (emp.isEmpty()) {
Employee employe = emp.get();
System.out.println(employe.getFirstName());
return employe;
} else {
System.out.println("ABSENT");
return null;
}
}
}
Additionnaly, the main and test classes :
package com.openclassrooms.api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.openclassrooms.api.models.Employee;
import com.openclassrooms.api.service.EmployeeService;
#SpringBootApplication
public class ApiApplication implements CommandLineRunner {
#Autowired
private EmployeeService employeeService;
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
public void run(String... args) throws Exception {
if (employeeService.getEmployee(1L).isPresent()) {
Employee emp1 = employeeService.getEmployee(1L).get();
System.out.println(emp1.getFirstName() + " " + emp1.getLastName());
} else {
System.out.println("Erreur, employé absent.");
}
System.out.println(employeeService.getEmployees());
}
}
package com.openclassrooms.api;
import static org.hamcrest.CoreMatchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import java.io.PrintStream;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
//import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.ResultHandler;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.openclassrooms.api.controller.EmployeeController;
import com.openclassrooms.api.models.Employee;
import com.openclassrooms.api.service.EmployeeService;
//#SpringBootTest
//#AutoConfigureWebMvc
#WebMvcTest(controllers = EmployeeController.class)
public class EmployeeControllerTest {
#Autowired
private MockMvc mockMvc;
#MockBean
private EmployeeService employeeService;
#Test
public void testGetEmployees() throws Exception {
Employee response = new Employee();
mockMvc.perform(get("/employee"))
.andExpect(status().isOk())
.andDo(print(System.out))
.andExpect(jsonPath("$.firstName").value("Laurent"));
//.andExpect(jsonPath("$[0].firstName", is("Laurent")));
}
}
Thanks in advance for any answer !
EDIT : the SQL script used when building the database :
DROP TABLE IF EXISTS employees;
CREATE TABLE employees (
id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(250) NOT NULL,
last_name VARCHAR(250) NOT NULL,
mail VARCHAR(250) NOT NULL,
password VARCHAR(250) NOT NULL
)
INSERT INTO employees (first_name, last_name, mail, password) VALUES
('Laurent', 'GINA', 'laurentgina#mail.com', 'laurent'),
('Sophie', 'FONCEK', 'sophiefoncek#mail.com', 'sophie'),
('Agathe', 'FEELING', 'agathefeeling#mail.com', 'agathe');
There seems to be a couple of issues with the code.
First, in the getEmployee method of the EmployeeController class, the if condition checks if the Optional returned by the employeeService is empty, but if it's empty, the code returns null, which is not the desired behavior. Instead, you should check if the Optional is present, and if it is, return the value, otherwise return an appropriate response indicating that the employee was not found.
#GetMapping("/employee/{id}")
public Employee getEmployee(#PathVariable("id") final Long id) {
Optional<Employee> emp = employeeService.getEmployee(id);
if (emp.isPresent()) {
Employee employe = emp.get();
System.out.println(employe.getFirstName());
return employe;
} else {
System.out.println("ABSENT");
// return an appropriate response indicating that the employee was not found
return null;
}
}
The same issue applies to the getEmployee method without a path variable.
#GetMapping("/employee")
public Employee getEmployee() {
Optional<Employee> emp = employeeService.getEmployee(1L);
if (emp.isPresent()) {
Employee employe = emp.get();
System.out.println(employe.getFirstName());
return employe;
} else {
System.out.println("ABSENT");
// return an appropriate response indicating that the employee was not found
return null;
}
}
Regarding the issue with the Junit test class, it's difficult to determine the problem without more information, such as the exact error message or a code snippet of the test class.
Overall, the code needs to be more robust in handling cases where the employee was not found, and the test class needs to be further investigated to determine the root cause of the issue.
I am working on hibernate. I have two entities: Project and Contact. These two entities have a one-to-many relationship. But, when I save a Project class, hibernate does not insert any record in Contact table(class) and just updates the Project table.
The business is;
There are lots of Projects. User select a project with double click which opens new jsp(got project id on that) and entering contact info and push Add button. What I am trying to do is the project that user selected is on db already. There is ok but I want to insert contact table with my contact info which include project_id. I am expecting from hibernate is update project table also insert contact table. But now reality is just updating project table only.
Here is structure of my classes: the main controller is Contact Controller.
Project.java:
package Model;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name="xxer_Projects_t")
public class Project {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int project_id;
#Column(name = "Project_number")
private String Project_number;
#Column(name = "Project_name")
private String Project_name;
#ManyToOne(fetch=FetchType.EAGER,cascade= {CascadeType.PERSIST,
CascadeType.MERGE,
CascadeType.DETACH,
CascadeType.REFRESH})
#JoinColumn(name = "constructor_id")
private Constructor constructor;
#OneToMany(fetch=FetchType.EAGER,mappedBy = "project",
cascade= {CascadeType.PERSIST,
CascadeType.MERGE,
CascadeType.DETACH,
CascadeType.REFRESH})
private List<Contact> contacts;
#OneToMany(fetch=FetchType.EAGER,mappedBy = "project",
cascade= {CascadeType.PERSIST,
CascadeType.MERGE,
CascadeType.DETACH,
CascadeType.REFRESH})
public List<Contact> getContacts() {
return contacts;
}
#OneToMany(fetch=FetchType.EAGER,mappedBy = "project",
cascade= {CascadeType.PERSIST,
CascadeType.MERGE,
CascadeType.DETACH,
CascadeType.REFRESH})
public void setContacts(List<Contact> contacts) {
this.contacts = contacts;
}
public Project() {
// TODO Auto-generated constructor stub
}
public Project(String project_number, String project_name) {
Project_number = project_number;
Project_name = project_name;
}
public int getProject_id() {
return project_id;
}
public void setProject_id(int project_id) {
this.project_id = project_id;
}
public String getProject_number() {
return Project_number;
}
public void setProject_number(String project_number) {
Project_number = project_number;
}
public String getProject_name() {
return Project_name;
}
public void setProject_name(String project_name) {
Project_name = project_name;
}
public Constructor getConstructor() {
return constructor;
}
public void setConstructor(Constructor constructor) {
this.constructor = constructor;
}
}
Contact.java:
package Model;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="xxer_contacts_t")
public class Contact {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String name_surname;
private String email;
private String phone;
#ManyToOne(fetch=FetchType.EAGER,cascade= {CascadeType.PERSIST,
CascadeType.MERGE,
CascadeType.DETACH,
CascadeType.REFRESH})
#JoinColumn(name = "project_id")
private Project project;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName_surname() {
return name_surname;
}
public void setName_surname(String name_surname) {
this.name_surname = name_surname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Project getProject_id() {
return project;
}
public void setProject_id(Project project_id) {
this.project = project_id;
}
public Contact() {
}
}
ContactController.java:
package Controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import Dao.ConstructorDao;
import Dao.ContactDao;
import Dao.ProjectDao;
import Model.Constructor;
import Model.Contact;
import Model.Project;
/**
* Servlet implementation class ContactController
*/
#WebServlet("/ContactController")
public class ContactController extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public ContactController() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int projectid = Integer.parseInt(request.getParameter("id"));
if (request.getParameter("Operation").equals("add")) {
String name = request.getParameter("NameSurname");
String email = request.getParameter("Email");
String phone = request.getParameter("Phone");
Project p = ProjectDao.getProjectById (projectid);
List <Contact> loc = new ArrayList<>();
Contact cont = new Contact();
cont.setName_surname(name);
cont.setEmail(email);
cont.setPhone(phone);
cont.setProject_id(p);
loc.add(cont);
p.setContacts(loc);
ProjectDao.insert(p);
/*
cont.setName_surname(name);
cont.setEmail(email);
cont.setPhone(phone);
cont.setProject_id(p);
ContactDao.Insert(cont);
*/
}
// List
List<Contact> ListOfContacts =ContactDao.getListofContacts(projectid);
request.setAttribute("ListOfContacts", ListOfContacts);
request.setAttribute("id", projectid);
RequestDispatcher dispacher = request.getRequestDispatcher("/ProjectContacts.jsp");
dispacher.forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
ProjectDao.java:
package Dao;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import Model.Constructor;
import Model.OfferType;
import Model.Project;
import _JSP.HibernateUtil;
public class ProjectDao {
public ProjectDao() {
// TODO Auto-generated constructor stub
}
/*
public static void main(String[] args) {
int id = 1;
Project p = new Project ("Proje3","TRIA Projesi");
insert(p);
}
*/
public static void insert(Project p) {
SessionFactory sf =HibernateUtil.getSessionFactory();
//SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session session = sf.openSession();
try {
session.beginTransaction();
//Constructor con = session.get(Constructor.class, consid);
//p.setConstructor(con);
//session.save(p);
//session.persist(p);
session.saveOrUpdate(p);
session.getTransaction().commit();
}
finally {
session.close();
System.out.println("Project Session Closed!!!!");
}
}
public static List<Project> getListofProjects() {
//SessionFactory sf = new Configuration().configure().buildSessionFactory();
SessionFactory sf =HibernateUtil.getSessionFactory();
Session session = sf.openSession();
//List <OfferType> ol = session.createCriteria(OfferType.class).list();
List <Project> ol =session.createQuery("from Project order by 1 desc").list();
session.close();
return ol;
}
public static Project getProjectById(int id) {
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session session = sf.openSession();
//List <OfferType> ol = session.createCriteria(OfferType.class).list();
Project p =session.get(Project.class,id);
session.close();
return p;
}
public static List<Constructor> LoadConsDropDown() {
SessionFactory sf = new Configuration().configure().buildSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
List <Constructor> listofcons = new ArrayList<Constructor>();
listofcons = session.createQuery("from Constructor order by name asc").list();
session.close();
return listofcons;
}
}
ContactDao.java:
package Dao;
import java.sql.SQLException;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Restrictions;
import Model.Contact;
import Model.Project;
import _JSP.HibernateUtil;
public class ContactDao {
public ContactDao() {
// TODO Auto-generated constructor stub
}
public static void Insert(Contact c) throws SQLException {
//SessionFactory sf = new Configuration().configure().buildSessionFactory();
SessionFactory sf =HibernateUtil.getSessionFactory();
Session session = sf.openSession();
try {
session.beginTransaction();
//Constructor con = session.get(Constructor.class, consid);
//p.setConstructor(con);
session.save(c);
session.getTransaction().commit();
}
finally {
session.close();
System.out.println("Contact Session Closed!!!!");
}
}
public static List<Contact> getListofContacts(int id) {
//SessionFactory sf = new Configuration().configure().buildSessionFactory();
SessionFactory sf =HibernateUtil.getSessionFactory();
Session session = sf.openSession();
//List <OfferType> ol = session.createCriteria(OfferType.class).list();
//List <Contact> ol =session.createCriteria(Contact.class).list();
List <Contact> ol = session.createCriteria(Contact.class).createAlias("project", "p").add(Restrictions.eq("p.project_id", id)).list();
session.close();
return ol;
}
}
I am developing a project in Spring Boot Billing. I have successfully build and run this project but there is some issue.
When i am trying insert data via POST method but Browser shows POST method not supported.
Here is my controller
BillingController.java
package com.billing.controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.billing.model.Restaurant_billing;
import com.billing.model.Restaurant_billingDao;
import com.billing.model.billing;
import com.billing.model.billingDao;
import com.billing.model.itemDao;
import com.billing.model.tax_billing;
import com.billing.model.tax_billingDao;
#Controller
#RestController
#RequestMapping("/restaurant")
public class BillingController {
#Autowired
private itemDao itemDao;
#Autowired
private billingDao billingDao;
#Autowired
private Restaurant_billingDao restaurant_billingDao;
#Autowired
private tax_billingDao tax_billingDao;
SessionFactory sessionFactory;
Session sesion=null;
org.hibernate.Transaction tx=null;
#RequestMapping(value="/create", method = RequestMethod.POST, consumes =
MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public String R_billing(#RequestBody final Restaurant_billing r_billing[] ,HttpServletResponse response,HttpServletRequest request)
throws ServletException {
try{
billing billingObject = new billing();
billingDao.save(billingObject);
int billing_id = billingObject.getId();
tax_billing tax_billing= new tax_billing();
tax_billing.setBilling_id(billing_id);
tax_billing.setTax_amount("140");
tax_billingDao.save(tax_billing);
for(Restaurant_billing prof:r_billing){
prof.setBilling_id(billing_id);
restaurant_billingDao.save(prof);
}
}
catch(Exception ex){
return "Error creating the user: " + ex.toString();
}
return ("User profession added successfully");
}
}
Here is my model class
Restaurant_billing.java
package com.billing.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name ="billing_restaurant")
public class Restaurant_billing {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(name="billing_id")
private int billing_id;
#Column(name="itemid")
private String itmeid;
#Column(name="quantity")
private String quantity;
#Column(name="billing_type")
private String billing_type;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getBilling_id() {
return billing_id;
}
public void setBilling_id(int billing_id) {
this.billing_id = billing_id;
}
public String getItmeid() {
return itmeid;
}
public void setItmeid(String itmeid) {
this.itmeid = itmeid;
}
public String getQuantity() {
return quantity;
}
public void setQuantity(String quantity) {
this.quantity = quantity;
}
public String getBilling_type() {
return billing_type;
}
public void setBilling_type(String billing_type) {
this.billing_type = billing_type;
}
}
No need to use #Controller use only #RestController and also assign sesion and tx values.
After that you just try the following code,
#RequestMapping(value = "/create", method = RequestMethod.POST)
public #RequestBody Restaurant_billing R_billing(final HttpServletResponse response){
try{
billing billingObject = new billing();
//Here set the billingObject values
billingDao.save(billingObject);
int billing_id = billingObject.getId();
tax_billing tax_billing= new tax_billing();
tax_billing.setBilling_id(billing_id);
tax_billing.setTax_amount("140");
tax_billingDao.save(tax_billing);
for(Restaurant_billing prof:r_billing){
prof.setBilling_id(billing_id);
restaurant_billingDao.save(prof);
}
}
catch(Exception ex){
return "Error creating the user: " + ex.toString();
}
return ("User profession added successfully");
}
//here return obj
}
I am using Jboss7.1 and jpa , ejb
I want to insert data -with OneToMany relationship- into my mysql database.
I have two entitys personne and voiture. I want to save a person in my database and associate voiture for him. The problem is that when i test my code (test), i find that there is a new personne added to my database and there is no voiture added in the table voiture
please can you help me .
code :
the entity personne
package com.domain;
import java.io.Serializable;
import javax.persistence.*;
import java.util.Set;
/**
* The persistent class for the personne database table.
*
*/
#Entity
public class Personne implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int idpersonne;
private String nom;
//bi-directional many-to-one association to Voiture
#OneToMany(mappedBy="personne")
private Set<Voiture> voitures;
public Personne() {
}
public Personne(String nom) {
super();
this.nom = nom;
}
public int getIdpersonne() {
return this.idpersonne;
}
public void setIdpersonne(int idpersonne) {
this.idpersonne = idpersonne;
}
public String getNom() {
return this.nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public Set<Voiture> getVoitures() {
return this.voitures;
}
public void setVoitures(Set<Voiture> voitures) {
this.voitures = voitures;
}
}
entity voiture
package com.domain;
import java.io.Serializable;
import javax.persistence.*;
/**
* The persistent class for the voiture database table.
*
*/
#Entity
public class Voiture implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private int idvoiture;
private String type;
//bi-directional many-to-one association to Personne
#ManyToOne
private Personne personne;
public Voiture() {
}
public Voiture(String type) {
super();
this.type = type;
}
public int getIdvoiture() {
return this.idvoiture;
}
public void setIdvoiture(int idvoiture) {
this.idvoiture = idvoiture;
}
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
public Personne getPersonne() {
return this.personne;
}
public void setPersonne(Personne personne) {
this.personne = personne;
}
}
this is the interface
package com.DAO;
import javax.ejb.Remote;
import com.domain.Personne;
#Remote
public interface PersonneDAO {
public void save(Personne personne);
public String sayhello();
}
the implementation
package com.DAO.Impl;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import com.DAO.VoitureDAO;
import com.domain.Voiture;
#Stateless
public class VoitureDAOImpl implements VoitureDAO {
#PersistenceContext(name = "JPADD")
EntityManager em;
#Override
public void save(Voiture voiture) {
em.persist(voiture);
}
}
the implementation
package com.DAO.Impl;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import com.DAO.PersonneDAO;
import com.domain.Personne;
#Stateless
public class PersonneDAOImpl implements PersonneDAO {
#PersistenceContext(name = "JPADD")
EntityManager em;
#Override
public String sayhello() {
// TODO Auto-generated method stub
return "helllllllllllllllllo";
}
#Override
public void save(Personne personne) {
em.persist(personne);
}
}
this is the test
package test;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.DAO.PersonneDAO;
import com.domain.Personne;
import com.domain.Voiture;
public class Test {
/**
* #param args
*/
public static void main(String[] args) {
Context intialcontext;
Properties properties = new Properties();
properties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
try {
intialcontext = new InitialContext(properties);
PersonneDAO dao = (PersonneDAO) intialcontext
.lookup("ejb:/projetweb/PersonneDAOImpl!com.DAO.PersonneDAO");
// /----------------------------objet voiture-------------
Voiture voiture = new Voiture("216");
Set<Voiture> voitures = new HashSet<Voiture>();
voitures.add(voiture);
// -------------------------------------------------------
Personne personne = new Personne("slatnia");
personne.setVoitures(voitures);
dao.save(personne);
} catch (NamingException e) {
e.printStackTrace();
}
}
}
and this is my jboss-ejb-client.properties
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=localhost
remote.connection.default.port = 4447
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
Try add following attributes to the #OneToMany annotation
#OneToMany(cascade=CascadeType.ALL)
You should add cascade = CascadeType.PERSIST in the #OneToMany
CascadeType.PERSIST
When persisting an entity, also persist the entities held in this
field. We suggest liberal application of this cascade rule, because if
the EntityManager finds a field that references a new entity during
flush, and the field does not use CascadeType.PERSIST, it is an error.
example:
#OneToMany(cascade = CascadeType.PERSIST)
private Set<Voiture> voitures;
Javadoc for CascadeType and other doc at here.
I've got a little 'complex' question.
I'm using Hibernate/JPA to make transactions with a DB.
I'm not the DBA, and a client consumes my application, a RESTful web service. My problem is that the DB is altered (not very often, but it still changes). Also, the client does not always respect input for my application (length, type, etc.). When this happens Hibernate throws an exception. The exception is difficult to translate and read from the log, because it has nested exceptions and consists of a lot of text: like I said, very difficult to understand.
I want to know if it's possible to handle exceptions on entity level, throwing maybe a customized exception.
I thank your patience and help in advance.
EDIT:
Fianlly I managed to do what I wanted, not sure if it's done the right way.
App.java
package com.mc;
import org.hibernate.Session;
import com.mc.stock.Stock;
import com.mc.util.HibernateUtil;
import javax.persistence.EntityManager;
public class App {
public static void main(String[] args) {
Set<ConstraintViolation<Stock>> violations;
validator = Validation.buildDefaultValidatorFactory().getValidator();
Scanner scan = new Scanner(System.in);
EntityManager em = null;
System.out.println("Hibernate one to many (Annotation)");
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Stock stock = new Stock();
String nextLine = scan.nextLine();
stock.setStockCode(nextLine.toString());
nextLine = scan.nextLine();
stock.setStockName(nextLine.toString());
violations = validator.validate(stock);
if (violations.size() > 0) {
StringBuilder excepcion = new StringBuilder();
for (ConstraintViolation<Stock> violation : violations) {
excepcion.append(violation.getMessageTemplate());
excepcion.append("\n");
}
System.out.println(excepcion.toString());
}
session.save(stock);
session.getTransaction().commit();
}
}
FieldMatch.java
package com.mc.constraints;
import com.mc.constraints.impl.FieldMatchValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
#Target({TYPE, ANNOTATION_TYPE})
#Retention(RUNTIME)
#Constraint(validatedBy = FieldMatchValidator.class)
#Documented
public #interface FieldMatch {
String message() default "{constraints.fieldmatch}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String first();
String second();
#Target({TYPE, ANNOTATION_TYPE})
#Retention(RUNTIME)
#Documented
#interface List {
FieldMatch[] value();
}
}
FieldMatchValidator.java
package com.mc.constraints.impl;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import com.mc.constraints.FieldMatch;
import org.apache.commons.beanutils.BeanUtils;
public class FieldMatchValidator implements ConstraintValidator<FieldMatch, Object> {
private String firstFieldName;
private String secondFieldName;
#Override
public void initialize(final FieldMatch constraintAnnotation) {
firstFieldName = constraintAnnotation.first();
secondFieldName = constraintAnnotation.second();
}
#Override
public boolean isValid(final Object value, final ConstraintValidatorContext context) {
try {
final Object firstObj = BeanUtils.getProperty(value, firstFieldName);
final Object secondObj = BeanUtils.getProperty(value, secondFieldName);
return firstObj == null && secondObj == null || firstObj != null && firstObj.equals(secondObj);
} catch (final Exception ignore) {
// ignore
}
return true;
}
}
Stock.java
package com.mc.stock;
import com.mc.constraints.FieldMatch;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.validator.constraints.Length;
#Entity
#Table(name = "STOCK")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Stock.findAll", query = "SELECT s FROM Stock s"),
#NamedQuery(name = "Stock.findByStockId", query = "SELECT s FROM Stock s WHERE s.stockId = :stockId"),
#NamedQuery(name = "Stock.findByStockCode", query = "SELECT s FROM Stock s WHERE s.stockCode = :stockCode"),
#NamedQuery(name = "Stock.findByStockName", query = "SELECT s FROM Stock s WHERE s.stockName = :stockName")})
#FieldMatch.List({
#FieldMatch(first = "stockCode", second = "stockName", message = "Code and Stock must have same value")
})
public class Stock implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_stock_id")
#SequenceGenerator(name = "seq_stock_id", sequenceName = "seq_stock_id", initialValue = 1, allocationSize = 1)
#Basic(optional = false)
#Column(name = "STOCK_ID", unique = true, nullable = false)
private Integer stockId;
#Column(name = "STOCK_CODE")
private String stockCode;
#Length(min = 1, max = 20, message = "{wrong stock name length}")
#Column(name = "STOCK_NAME")
private String stockName;
public Stock() {
}
public Stock(Integer stockId) {
this.stockId = stockId;
}
public Integer getStockId() {
return stockId;
}
public void setStockId(Integer stockId) {
this.stockId = stockId;
}
public String getStockCode() {
return stockCode;
}
public void setStockCode(String stockCode) {
this.stockCode = stockCode;
}
public String getStockName() {
return stockName;
}
public void setStockName(String stockName) {
this.stockName = stockName;
}
#Override
public int hashCode() {
int hash = 0;
hash += (stockId != null ? stockId.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Stock)) {
return false;
}
Stock other = (Stock) object;
if ((this.stockId == null && other.stockId != null) || (this.stockId != null && !this.stockId.equals(other.stockId))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.mc.stock.Stock[ stockId=" + stockId + " ]";
}
}
HibernateUtil.java
package com.mc.util;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// Create the SessionFactory from hibernate.cfg.xml
return new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdown() {
// Close caches and connection pools
getSessionFactory().close();
}
}
Oracle DB Structure
CREATE TABLE stock
(
STOCK_ID NUMBER(5) NOT NULL ,
STOCK_CODE VARCHAR2(10) NULL ,
STOCK_NAME VARCHAR2(20) NULL
);
ALTER TABLE stock
add CONSTRAINT PK_STOCK_ID PRIMARY KEY (STOCK_ID);
create sequence seq_stock_id
start with 1
increment by 1
nomaxvalue;
I'm inclined to do as much validation before you get the the DB level. Have a look at Hibernate Validator, http://www.hibernate.org/subprojects/validator.html which is the reference implementation of JSR-303.
Using standard annotations you can enforce constraints and get good error messages before you attempt to put the entities into your database.
I believe this will allow you to validate at the entity level as requested.
I am not sure what you mean about "entity level", but sure. Put a try/catch around the code that is invoking Hibernate. Catch Throwable and rethrow whatever you want. The trick is putting some reason that makes sense in the exception you are throwing.
Of course, one major point is that you should validate all input.
You can implement your own SQLExceptionConverter and handle it the way you want.
Use the property 'hibernate.jdbc.sql_exception_converter' to set your custom converter.
I am unable to find more documentation this, you need to dig into implementations by Hibernate to find more.
By the way, why can't you have a global filter, which catches every exception and decide which exception to re throw as it is or throw a new exception? You will be doing more or less same even if you implement your own SQLExceptionConverter.
according to my experience, you should catch the SQLException, and then u can get easily the SQL error code for specific database.
Eg: your database is mysql and u got error code 1062 . So you can know that error is Duplicated entry error. You can check the mysql error code
http://www.briandunning.com/error-codes/?source=MySQL