how to map single entity with multiple table in jpa - spring-boot

I create tour and travel app using xspringboot and Hibernate jpa.in
that application i have two entity class one is turist and other is
vechileTtype.I want to map vechiletype entity with turist entity. I
use xaamp server for my sql database. but when i mapped these two
entity and run the application i get this type of error
Repeated column in mapping for entity: com.main.ToursTravels.model.VechileType column: name (should be mapped with insert="false" update="false")
Turist.java
package com.main.ToursTravels.model;
import java.math.BigDecimal;
import java.util.Date;
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.OneToOne;
import javax.persistence.Table;
import lombok.Data;
#Entity
#Table(name="turist")
#Data
public class Turist {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="truist_id")
private Long truistid;
#Column(name="turistname")
private String turistname;
#Column(name="travel_km")
private int travelkm;
#Column(name="travel_date")
private Date traveldate;
#Column(name="drivername")
private String drivername;
#OneToOne(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
#JoinColumn(name="booking_id")
private VechileType vechiletype;
#Column(name="vechileno")
private String vechileno;
#Column(name="total_amount")
private BigDecimal totalamount;
#Column(name="BOOKING_status")
private boolean bookingstatus;
}
VechileType.java
package com.main.ToursTravels.model;
import java.math.BigDecimal;
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.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import lombok.Data;
#Entity
#Table(name="vechiletype")
#Data
public class VechileType {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="booking_id")
private Long bookingid;
#OneToOne(fetch=FetchType.LAZY,cascade=CascadeType.ALL,mappedBy="vechiletype")
private Turist turist;
#Column(name="name")
private boolean mini;
#Column(name="name")
private boolean sedan;
#Column(name="name")
private boolean suv;
#Column(name="name_per_km")
private int rateperkm;
private BigDecimal minprice;
}
application.properties
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/groserystore?useSSL=false & serveTimezone= UTC & useLegacyDateTimeCode=false
spring.datasource.username=root
spring.datasource.password=
#use of jpa
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.JPA.hibernate.ddl.auto=update

You are mapping 3 different properties to the same column name:
#Column(name="name")
private boolean mini;
#Column(name="name")
private boolean sedan;
#Column(name="name")
private boolean suv;
Use different names instead:
#Column(name="mini")
private boolean mini;
#Column(name="sedan")
private boolean sedan;
#Column(name="suv")
private boolean suv;
A better, more extensible alternative could be to use an enum:
public enum VehicleKind {
MINI, SEDAN, SUV
}
And in VechileType
#Entity
#Table(name="vechiletype")
#Data
public class VechileType {
#Enumerated(EnumType.STRING)
private VehicleKind kind;

Related

Joining tables and returning data to react with Spring JPA

I am trying to join two entities in Spring JPA so that I can access the data in react.
I have an Event and Course entity with corresponding tables in postgres.
In react I loop through all the events in the database and display them on a card for each event. The Event table contains the courseid where that event is being played at. But I want to show on the card the coursename rather than the courseid.
I dont currently have access to this so need to join the tables so I have access to it.
I have never used queries in Spring JPA and struggling to create one to make this join.
I want something like this SQL query,
select * from event join course on course.courseid=event.course_id where eventid=5
where the eventid will be passed from react to Spring so that during each loop, it will get the correct eventid and display the corresponding coursename for that event.
Implementation:
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
#Entity
public class Course {
#Id
#Column(name = "courseid")
private Long id;
#Column(name = "coursename")
private String courseName;
#OneToMany(mappedBy = "course")
private List<Event> events;
// ...
}
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
#Entity
public class Event {
#Id
#Column(name = "eventid")
private Long id;
#ManyToOne
#JoinColumn(name = "course_id")
private Course course;
// ...
}
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface EventRepository extends JpaRepository<Event, Long> {
}
Usage:
import java.util.Map;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class MyController {
#Autowired
private EventRepository eventRepository;
#GetMapping
public Map<String, ? extends Object> index(#RequestParam("id") final long id) {
// find by eventid
final Optional<Event> res = eventRepository.findById(id);
res.ifPresent(e -> {
// course name
System.out.println(e.getCourse().getCourseName());
});
return res.map(e -> Map.of("id", e.getId(), "course", e.getCourse().getCourseName()))
.orElse(Map.of());
}
}

How to remove ID field while inserting values through CommandLineRunner

Well I just started learning spring boot, I work for the moment on a little project inserting Data into Database.
This is understood that "Id" shall be self created since I've include #GeneratedValue method. The problem is Intellij auto assigned property names to my data, which is prevent data entering to the database,i copy also image
Due to this auto property assigning act by intellij I'm unable to enter data in to database & getting an error (this is what I understand):
/home/kash/Documents/test/demos/src/main/java/com/example/demos/StudentConfig.java:18:32
java: constructor Student in class com.example.demos.Student cannot be applied to given
types;
required:
java.lang.Long,java.lang.String,java.lang.String,java.time.LocalDate,java.lang.Integer
found: java.lang.String,java.lang.String,java.time.LocalDate,int
reason: actual and formal argument lists differ in length
I'm looking for an advise, grateful for the help I copy all the script hereunder.
Student.java
package com.example.demos;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.time.LocalDate;
#Getter
#Setter
#AllArgsConstructor
#Entity
#Table
public class Student {
#Id
#SequenceGenerator(
name = "student_sequence",
sequenceName = "student_sequence",
allocationSize = 1
)
#GeneratedValue(
strategy = GenerationType.SEQUENCE,
generator = "student_sequence"
)
private Long id;
private String name;
private String email;
private LocalDate dob;
private Integer age;
}
StudentRepository.java
package com.example.demos;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface StudentRepository
extends JpaRepository <Student, Long> {
}
StudentService.java
package com.example.demos;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.Month;
import java.util.List;
#Service
#AllArgsConstructor
public class StudentService {
#Autowired
private final StudentRepository studentRepository;
List<Student> getStudents(){
return studentRepository.findAll();
}
}
StudentConfig.java
package com.example.demos;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.LocalDate;
import java.util.List;
import static java.util.Calendar.MAY;
#Configuration
public class StudentConfig {
#Bean
CommandLineRunner commandLineRunner(
StudentRepository repository){
return args -> {
Student John = new Student(
"John Doe",
"john#hotmail.com",
LocalDate.of(2010, MAY, 19 ),
11
);
Student Haider = new Student(
"Haider",
"Haider#hotmail.com",
LocalDate.of(2024, MAY, 10 ),
2
);
repository.saveAll(
List.of(John, Haider)
);
};
}
}

Spring Boot - Response empty

the API gives me an empty answer. If I debug the variable it appears full but at the time of the return it arrives empty, the table contains data and I load it by hand and if I do "SELECT * FROM clients" it brings me these data, what I do not understand is that when he returns it appears empty
CLASS
package com.gestion.backend.entidades;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Data;
#Entity
#Table(name="clientes")
#Data
public class Cliente {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column
private Long id;
#Column
private String nombre;
#Column
private String apellido;
#Column
private String email;
#Column
private String localidad;
#Column
private String provincia;
#Column(name="tipo_documento")
private String tipoDocumento;
#Column
private String documento;
#Column
private String nacionalidad;
#Column(name="codigo_postal")
private String codigoPostal;
#Column
private String direccion;
#Column(name="telefono_fijo")
private String telefonoFijo;
#Column
private String celular;
#Column(name="telefono_alternativo")
private String telefonoAlternativo;
#Column(name="forma_de_pago")
private String formaDePago;
#Column
private String condiciones;
}
CONTROLLER
package com.gestion.backend.controllers;
import java.util.List;
import com.gestion.backend.entidades.Cliente;
import com.gestion.backend.services.ClientesService;
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;
#RestController
public class ClientesController {
#Autowired
ClientesService clientesService;
// Traigo todos los usuarios
#GetMapping("/clientes")
public List<Cliente> getClientes(){
List<Cliente> clientes = clientesService.getClientes();
//return clientesService.getClientes();
return clientes;
}
// Traigo un usuario especifico
#GetMapping("/clientes/{id}")
public Cliente getClientes(#PathVariable Long id){
return clientesService.getClientesById(id);
}
}
SERVICE
package com.gestion.backend.services;
import java.util.List;
import com.gestion.backend.entidades.Cliente;;
public interface ClientesService {
// Metodos para la clase Clientes
public List<Cliente> getClientes();
public Cliente getClientesById(Long id);
}
SERVICE IMPL
package com.gestion.backend.services.implementation;
import com.gestion.backend.dao.ClientesRepository;
import com.gestion.backend.entidades.Cliente;
import com.gestion.backend.services.ClientesService;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class ClientesServiceImpl implements ClientesService {
#Autowired
private ClientesRepository clientesRepository;
public List<Cliente> getClientes(){
return clientesRepository.findAll();
}
public Cliente getClientesById(Long id){
return clientesRepository.findById(id);
}
}
REPOSITORY
package com.gestion.backend.dao;
import java.util.List;
import java.io.Serializable;
import org.springframework.stereotype.Repository;
import com.gestion.backend.entidades.Cliente;
import org.springframework.data.jpa.repository.JpaRepository;
#Repository("clientesRepository")
public interface ClientesRepository extends JpaRepository<Cliente, Serializable>{
List<Cliente> findAll();
Cliente findById(Long id);
//void softDelete(Integer id);
}
SELECT FROM HIBERNATE
Hibernate: select cliente0_.id as id1_0_, cliente0_.apellido as apellido2_0_, cliente0_.celular as celular3_0_, cliente0_.codigo_postal as codigo_p4_0_, cliente0_.condiciones as condicio5_0_, cliente0_.direccion as direccio6_0_, cliente0_.documento as document7_0_, cliente0_.email as email8_0_, cliente0_.forma_de_pago as forma_de9_0_, cliente0_.localidad as localid10_0_, cliente0_.nacionalidad as naciona11_0_, cliente0_.nombre as nombre12_0_, cliente0_.provincia as provinc13_0_, cliente0_.telefono_alternativo as telefon14_0_, cliente0_.telefono_fijo as telefon15_0_, cliente0_.tipo_documento as tipo_do16_0_ from clientes cliente0
Does anyone know why it returns empty? [{}]
Thanks!!!

#Notnull on update not on add

I have a model class which is used in post(create) and put(update) rest API
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.Setter;
#Getter
#Setter
#NoArgsConstructor
#Entity(name= "employee")
public class employeeDetail {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long employeeId;
#NonNull
private String employeeName;
}
So since employee id to be nullable on add, while it has to be passed when update operation. What is the best to implement?
Note: In this case employee id is a primary key, the same situation is possible for non-primary key fields as well. I use Spring boot, Spring data JPA and hibernate. Database is mariadb.
Something like this:
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.transaction.Transactional;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.Optional;
#Getter
#Setter
#NoArgsConstructor
#Entity(name = "employee")
class EmployeeDetail {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long employeeId; //Long is better!
#NotNull
private String employeeName;
// Needed just for conversion -> use some mapper, and remove this constructor
public EmployeeDetail(EmployeeDetailDTO employeeDetailDTO) {
this.employeeId = employeeDetailDTO.getEmployeeId();
this.employeeName = employeeDetailDTO.getEmployeeName();
}
}
interface EmployeeDetailRepo extends JpaRepository<EmployeeDetail, Long> {
}
#Data
#JsonInclude(JsonInclude.Include.NON_NULL)
class EmployeeDetailDTO {
private Long employeeId;
#NotNull
private String employeeName;
// Other fields
// Needed just for conversion -> use some mapper, and remove this constructor
public EmployeeDetailDTO(EmployeeDetail employeeDetail) {
this.employeeId = employeeDetail.getEmployeeId();
this.employeeName = employeeDetail.getEmployeeName();
}
}
#Service
class EmpDetailService {
private EmployeeDetailRepo employeeDetailRepo;
#Autowired
public EmpDetailService(EmployeeDetailRepo employeeDetailRepo) {
this.employeeDetailRepo = employeeDetailRepo;
}
public EmployeeDetailDTO add(EmployeeDetailDTO employeeDetailDTO) {
// map EmployeeDetailDTO to EmployeeDetail
EmployeeDetail employeeDetail = new EmployeeDetail(employeeDetailDTO);
EmployeeDetail employeeDetail1FromDB = employeeDetailRepo.save(employeeDetail);
// map back to dto
return new EmployeeDetailDTO(employeeDetail1FromDB);
}
#Transactional
public EmployeeDetailDTO edit(Long id, EmployeeDetailDTO employeeDetailDTO) {
// map EmployeeDetailDTO to EmployeeDetail
Optional<EmployeeDetail> byId = employeeDetailRepo.findById(id);
EmployeeDetail employeeDetailFromDB = byId.orElseThrow(() -> new RuntimeException("No such user with id: " + id));
employeeDetailFromDB.setEmployeeName(employeeDetailDTO.getEmployeeName());
return new EmployeeDetailDTO(employeeDetailFromDB);
}
}
#RequestMapping
class Controller {
private EmpDetailService empDetailService;
#Autowired
Controller(EmpDetailService empDetailService) {
this.empDetailService = empDetailService;
}
#PostMapping("/add")
public ResponseEntity<EmployeeDetailDTO> add(#Valid #RequestBody EmployeeDetailDTO employeeDetailDTO) {
EmployeeDetailDTO added = empDetailService.add(employeeDetailDTO);
return new ResponseEntity<>(added, HttpStatus.OK);
}
#PostMapping("/edit/{id}")
public ResponseEntity<EmployeeDetailDTO> edit(#PathVariable Long id,
#Valid #RequestBody EmployeeDetailDTO employeeDetailDTO) {
EmployeeDetailDTO edited= empDetailService.edit(id, employeeDetailDTO);
return new ResponseEntity<>(edited, HttpStatus.OK);
}
}
Since you expect Hibernate to generate yuor id on insert it should be nullable, so its type.
Just change employeeId to Integer.
From a design point of view, consider to create 2 different business domain classes, one for insert with no id and one for update/select with non nullable id.
public class EmployeeRegistration {
#NonNull
private String name;
}
public class EmployeeDetail {
#NonNull
private Integer employeeId;
#NonNull
private String name;
}
Then provade methods to transform them to database entities.

How to write query by using findBy..() methods for one record

I've an entity class User_Details
package vl.cybersecurityapplication.model;
import java.io.Serializable;
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 = "User_Details")
public class User_Details implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "UserId")
private int userId;
#Column(name = "FirstName")
private String firstName;
#Column(name = "LastName")
private String lastName;
#Column(name = "Password")
private String password;
#Column(name = "E_Mail")
private String eMail;
#Column(name = "Mobile_Num")
private int mobileNumber;
//getters and setters
}
Here is my repo interface
package vl.cybersecurityapplication.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import vl.cybersecurityapplication.model.User_Details;
public interface IUserRepository extends JpaRepository<User_Details, Long> {
public Integer findMobileNumberByName(String userName);
}
This is my repo class
package vl.cybersecurityapplication.repository;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Repository;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import vl.cybersecurityapplication.model.User_Roles;
#Transactional
#Repository
public class UserRepository{
#Autowired
IUserRepository userRepository;
public Integer findMobileNumberByName(#PathVariable String lastName) {
int mobileNumber = userRepository.findMobileNumberByName("shaik");
System.out.println("Mobile Number : "+mobileNumber);
return mobileNumber;
}
}
I'm new to Spring Boot and JPA.
Here I need to query mobile number in User_Details table by using lastname.
i.e., Select Mobile_Num from User_Details where LastName= "xyz";
Can Some one help me how to wo write this query in my repo class.
You can write like this. But you cannot fetch only MobileNumber. You will get a complete object.
List<User> findByLastName(String lastname).
If you want to get only some fields then you should check out Projections
No need to use a native query. JPA supports object based query.
You can use List findByLastName(String lastname) which will generate that query in the backend and return the result.

Resources