Entity creates useless id field - json

I have a CrudRepository with two entities.
Problem: The characteristic entity always creates an additional id field in the database but does not select the correct characteristic_id field to generate JSON.
machine entity
machine_id || name || description
characteristic entity
characteristic_id || machine_id || name || description || type || value
Question: Why does the characteristic entity always create an id field named id and does not use the definded filed characteristic_id?
JSON
How the entity manipulates the database layout:
Machine entity
#Entity
#Table(name = "maschine")
public class Machine {
private int machine_id;
private String name;
private String description;
private Set<Characteristic> characteristics;
#OneToMany(fetch = FetchType.EAGER, mappedBy = "machine", cascade = CascadeType.ALL)
public Set<Characteristic> getCharacteristics() {
return characteristics;
}
public void setCharacteristics(Set<Characteristic> characteristics){
this.characteristics = characteristics;
}
public Machine(){}
public Machine(String name, String description){
this.name = name;
this.description = description;
}
#Override
public String toString() {
return "Machine [id=" + machine_id + ", name=" + name + ", description=" + description + "]";
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="id")
public int getId() {
return machine_id;
}
public void setId(int machine_id) {
this.machine_id = machine_id;
}
#Column(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Column(name="description")
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
Characteristic entity
#Entity
#Table(name = "characteristic")
public class Characteristic {
private int characteristic_id;
private String name;
private String description;
private int type;
private int value;
private Machine machine;
#ManyToOne
#JoinColumn(name="machine_id")
public Machine getMachine(){
return machine;
}
public void setMachine(Machine machine){
this.machine = machine;
}
public Characteristic() {}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="id")
public int getCharacteristic_Id() {
return characteristic_id;
}
public void setCharacteristic_Id(int characteristic_id) {
this.characteristic_id = characteristic_id;
}
#Column(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Column(name="description")
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Column(name="type")
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
#Column(name="value")
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
#Override
public String toString() {
return "Characteristic [id=" + characteristic_id + ", name=" + name + ", description=" + description + ", type=" + type
+ ", value=" + value + "]";
}
}
My CrudRepository to interact with the database:
public interface MachineRepository extends CrudRepository<Machine, Integer>{
}
My Controller:
#RestController
public class HomeController {
private final MachineRepository machineRepository;
#Autowired
HomeController(MachineRepository machineRepository) {
this.machineRepository = machineRepository;
}
#RequestMapping(value = "/machine", method = RequestMethod.GET)
Collection<Machine> readMachines(){
return (Collection<Machine>) machineRepository.findAll();
}
}
This is all code I have written for the database operations..

Change to this code
#Id
#GeneratedValue
#Column(name="id", nullable = false)
public int getCharacteristic_id() {
return characteristic_id;
}

By default as you have not specified the column name in your configuration hibernate will use the name of the getter methode without "get" part as the column name in the table. Below is the configuration in your Characteristic Entity
#Id
#GeneratedValue
public int getId() {
return characteristic_id;
}
As you have not specified any explicit column name for the memeber characteristic_id , hibernate by default chooses Id (removing get from the getId() method) as the column name for the member. And hence it always creates a column named Id for you characteristics_id member .
In order to force hibernate to use characteristic_id as the column name , you can use #Column annotation and provide the column name as characteristics_id
apart from the #Id and #GeneratedValue you are using to mark the getter.
#Id
#GeneratedValue
#Column(name="characteristic_id")
public int getId() {
return characteristic_id;
}
or you can change the name of getter and setter as below
#Id
#GeneratedValue
public int getCharacterisitc_id() {
return characteristic_id;
}
public void setCharacterisitc_id(int characteristic_id) {
this.characteristic_id = characteristic_id;
}

Related

Spring JDBC Unable to insert

I am new to SpringBoot and I am using SpringBoot with JDBC for making an API. The INSERT is not working properly, I had made ID Unique and AutoIncremeneted it. Before I was inserting the ID and it was causing no problems.I am using MySql as the database.
The JSON I am using in POST is:
{
"name":"Name",
"email":"namegmail.com",
"dob":"2000-04-09",
"age":21
}
I am getting this Error.
{
"timestamp": "2021-06-20T13:10:16.925+00:00",
"status": 415,
"error": "Unsupported Media Type",
"message": "Content type 'application/octet-stream' not supported",
"path": "/api/v1/NewStudent"
}
Controller
#RestController
#RequestMapping(path = "api/v1/")
public class StudentController {
private StudentService studentService;
#Autowired
public StudentController(StudentService service){
this.studentService=service;
}
#GetMapping("/home")
public String getHome(){
return "Hey Welcome to Home";
}
#PostMapping("/NewStudent")
public void registerNewStudent(#RequestBody StudentClass studentClass){
studentService.addNewStudent(studentClass);
}
#GetMapping("/student/{id}")
public StudentClass getStudentSearch(#PathVariable(value = "id") Long userId){
return studentService.getStudentSelect(userId);
}
#GetMapping("/AllStudents")
public List<StudentClass> getAllStudents(){
return studentService.getAllStudents();
}
}
StudentDao
public class StudentDaoClass implements StudentDao{
#Autowired
private JdbcTemplate jdbctemplate;
private List<StudentClass> selectAll;
#Override
public int insert(StudentClass student) {
String query="INSERT INTO Student(std_name,std_email,std_dob,std_age)" +
"VALUES(?,?,?,?)";
int res=this.jdbctemplate.update(query,student.getName(),student.getEmail(),student.getDob(),student.getId());
return res;
}
#Override
public StudentClass selectStudent(Long id) {
String query="SELECT * FROM Student WHERE std_id=?";
RowMapper<StudentClass> rowMapper=new RowMapperClass();
StudentClass studentClass=this.jdbctemplate.queryForObject(query,rowMapper,id);
return studentClass;
}
#Override
public List<StudentClass> selectAllStudents() {
String query="SELECT * FROM Student";
selectAll=this.jdbctemplate.query(query,new RowMapperClass());
return selectAll;
}
public JdbcTemplate getJdbctemplate() {
return jdbctemplate;
}
public void setJdbctemplate(JdbcTemplate jdbctemplate) {
this.jdbctemplate = jdbctemplate;
}
}
StudentClass
public class StudentClass {
#Id
private Long id;
private String name;
private LocalDate dob;
private Integer age;
private String email;
public StudentClass() {
}
public StudentClass(String name, String email,LocalDate dob ,Integer age) {
this.name = name;
this.dob = dob;
this.age = age;
this.email = email;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public LocalDate getDob() {
return dob;
}
public void setDob(LocalDate dob) {
this.dob = dob;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Override
public String toString() {
return "StudentClass{" +
"id=" + id +
", name='" + name + '\'' +
", dob=" + dob +
", age=" + age +
", email='" + email + '\'' +
'}';
}
}
I think your rest call is not even reaching the jdbc part as there is problem in your rest request. I believe you are not setting the content-type properly. Try making below changes and see.
When sending the request please set 'Content-Type' header property to 'application/json'
and enhance your below handler method what is consumes.
#PostMapping(path="/NewStudent", consumes="application/json")
public void registerNewStudent(#RequestBody StudentClass studentClass){
studentService.addNewStudent(studentClass);
}
Try debugging your application. Your rest call should reach your above handler method.

JAVA Spring boot how to post arraylist in Postman

I am trying to save some books via request but I am getting errors. How do I exactly do this? This is the model
#Entity
public class Reservation {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String user;
private int period;
#OneToMany
private List<Books> books;
public static String error () {
return "Input error";
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public int getPeriod() { return period;}
public void setPeriod(int period) {this.period = period;}
public List<Books> getBooks() { return books;}
public int getId() {return id;}
public void setId(int id) {this.id = id;}
#Entity
public class Books implements Serializable {
#Id
#GeneratedValue( strategy = GenerationType.IDENTITY )
private int id;
private String name;
}
}
Controller:
#PostMapping("/reserveBook")
public String reserveBook(#RequestBody Reservation reservation)
{
if (reservation.getPeriod() > 2)
return Book.error();
else{
reserveRepo.save(reservation);
return "success";
}
}
Tried json like this
{
"user": "Jason",
"books":[{"name": "Wonders"}, {"name": "Good classics"}],
"period": 2
}
What exact error you are getting? Can you try to make your inner class static? Like
public static class Books implements Serializable

No adding entity in a manytoone relationship using spring boot and jpa

I'm new in spring boot, I'm looking for help with this problem: I have two entities connected by a ManytoOne relationship. The entities are course and professor.
The professor Entity:
#Entity
#Table(name = "professor")
public class Professor implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long idProfessor;
private String name;
private String lastName;
private String phone;
private String mail;
#Fetch(FetchMode.JOIN)
#OneToMany(mappedBy = "professor", cascade= CascadeType.ALL)
private List<Course> courses;
public Professor() {
}
public Long getIdProfessor() {
return idProfessor;
}
public void setIdProfessor(Long idProfessor) {
this.idProfessor = idProfessor;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
}
The Course Entity:
#Entity
#Table(name = "course")
public class Course implements Serializable {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long idCourse;
private String title;
private String description;
#ManyToOne
#JoinColumn(name="professor_id")
private Professor professor;
#ManyToMany(mappedBy = "courses")
private List<Student> students;
public Course() {}
public Long getIdCourse() {
return idCourse;
}
public void setIdCourse(Long idCourse) {
this.idCourse = idCourse;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
I also created a rest controller to create Course and I defined POST endpoint like this:
#PostMapping(value="/create")
public Course createCourse(#RequestBody Course course) {
return courseRepo.save(course);
}
When I add a new course in postman, the course is added but it is not assigned to the corresponding professor (an existing professor in the database), "idProfessor" is always assigned to NULL. Here is an example of POST API execution in postman and the result in MySQL.
postman
mysql
Any suggestions?

Spring Boot: How to retrieve the username by user_id?

I have already connected my springboot to MySQL database. I want to display the username when user_id is specified in the HTTP request. e.g. http://8080/user/1 must display the name of the user with user_id 1.
The table contains attributes as:
| Integer user_id; | String username; | String fathername; | String mothername;
I have already tried this code in by Controller class but i does not seem to be working
#RequestMapping("/{userid}")
#ResponseBody
public String getById(Integer userid) {
String name="";
try {
Optional<Persondetails> persondetails=persondetailsRepository.findById(personid);
name = String.valueOf(userdetails.getName());
}
catch (Exception ex) {
return "Name not found";
}
return "The Name of the user is : " + name;
}
my repository code:
import java.util.List;
import java.util.Optional;
public interface UserdetailsRepository extends JpaRepository<Userdetails, Integer> {
public Optional<Userdetails> findById(Integer userid);
}
It says getName() is undefined for the type Optional
But i have defined it in Userdetails class
public class Userdetails {
#Id
#GeneratedValue
#Column(name="user_id")
private Integer userid;
#Column(name="name")
private String name;
#Column (name="fathers_name")
private String fathersname;
#Column(name="mothers_name")
private String mothersname;
public Userdetails() {
}
public Integer getUserid() {
return userid;
}
public void setUserid(Integer userid) {
this.userid = userid;
}
public String getName() {
return name;
}
public void setname(String name) {
this.name = name;
}
public String getFathersname() {
return fathersname;
}
public void setFathersname(String fathersname) {
this.fathersname = fathersname;
}
public void setMothersname(String mothersname) {
this.mothersname = mothersname;
}
public String getMothersname() {
return mothersname;
}
}
It's missing the method type GET, you can do by two options:
#RequestMapping(value = "/{id}", method = RequestMethod.GET)
public User findOne(#PathVariable("id") int id){
return userService.findById(id);
}
OR
#GetMapping("/{id}")
public String getString(#PathVariable("id") int id) {
return "Helloworld";
}
Spring boot Connect with Mysql and get Data.
application.properties
server.contextPath=/demo-user
spring.datasource.url=jdbc:mysql://localhost:3306/testdb
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
*Controller.Java
#RequestMapping({"/users"})
public class UserController {
#Autowired
private UserService userService;
#GetMapping(path = {"/{id}"})
public User findOne(#PathVariable("id") int id){
return userService.findById(id);
}
}
UserService.java
public interface UserService {
User findById(int id);
}
UserServiceImpl.java
#Service
public class UserServiceImpl implements UserService {
#Autowired
private UserRepository repository;
#Override
public User findById(int id) {
return repository.findOne(id);
}
}
UserRepository .java
public interface UserRepository extends Repository<User, Integer> {
User findOne(int id);
}
User.java
#Entity
#Table(name = "user")
public class User {
#Id
#Column
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column
private String firstName;
#Column
private String lastName;
#Column
private String email;
//setter and getter
}
Make request from browser or application.
http://localhost:8080/demo-user/users/1

Spring Boot: Saving a one to many json request, foreign key is not saved automatically

I have 2 entities, Role and Resource. A role can have many resources.
#Entity
public class Resource {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(name="firstname")
private String firstName;
#Column(name="lastname")
private String lastName;
private String email;
#ManyToOne
#JoinColumn(name="roleId", nullable = false)
private Role role;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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 getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}
#Entity
public class Role {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(name = "rolename")
private String roleName;
#OneToMany(mappedBy = "role", cascade = CascadeType.ALL)
private List<Resource> resources;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public List<Resource> getResources() {
return resources;
}
public void setResources(List<Resource> resources) {
this.resources = resources;
}
}
I'm trying to save a Role object that has a resource in it. This is the body of my json in postman.
{
"roleName" : "Business Analyst",
"resources" : [{
"firstName" : "John",
"lastName" : "Doe",
"email" : "John#Doe.com"
}]
}
http post call in postman:
http://localhost:8080/app/admin/roles/role
Role Controller
#RestController
#RequestMapping(value="/admin/roles")
public class RoleController {
#Autowired
private RoleService roleService;
private static final Logger log = LoggerFactory.getLogger(RoleController.class);
#RequestMapping(value="/role", method = RequestMethod.POST)
public ResponseEntity<?> addRole(#RequestBody Role role, UriComponentsBuilder ucBuilder){
log.info("Adding Role {}" + role);
log.info("Adding Rolename:" + role.getRoleName());
roleService.addRole(role);
HttpHeaders headers = new HttpHeaders();
headers.setLocation(ucBuilder.path("/admin/roles/role/{id}").buildAndExpand(role.getId()).toUri());
return new ResponseEntity<String> (headers,HttpStatus.CREATED);
}
#RequestMapping(value="role", method = RequestMethod.GET)
public ResponseEntity<List<Role>> listAllRoles(){
List<Role> roles = roleService.getAllRoles();
return new ResponseEntity<List<Role>>(roles, HttpStatus.OK);
}
}
RoleRepository
public interface RoleRepository extends CrudRepository<Role, Integer> {
}
RoleService
public interface RoleService {
public void addRole(Role role);
}
RoleServiceImpl
#Service
public class RoleServiceImpl implements RoleService {
#Autowired
private RoleRepository roleRepository;
#Override
public void addRole(Role role) {
roleRepository.save(role);
}
}
Whats happening is, the role Business Analyst gets save in the roleName field of Role table. The id of the said row is auto generated. At the same time, the resource with firstName = John, lastName = Doe and email = John#Doe.com gets save in the Resource table.
However, the role_id is not being saved automatically in the Resource table so now it is null ( the table Resource has the role_id set to nullable ). I was expecting that when I do the json post, the data will be automatically saved in the Role table and also the Resource table. Both of these are happening except that the role_id is not being saved. What did I miss?
Change addRole like below :
public void addRole(Role role) {
for(Resource resource: role.getResources()){
resource.setRole(role);
}
roleRepository.save(role);
}