Function saves new record for room table instead of booking table (booking table has room_id as foreign key) - spring

Ive tried to save record for booking in the bookings table, but it does not create a record and instead adds a room for the room table which i do not want as the room table is not supposed to change, only records of bookings should be added into the bookings table with a foreign key room_id of the room that was booked.
Any help would be much appreciated! Thanks!
Tbl_Bookings Entity
package com.sam.ResourceBookingMS.model;
import java.io.Serializable;
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.Table;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
#Entity
#Table(name = "Tbl_Bookings")
public class Tbl_Bookings implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "booking_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public Integer getEmployee_id() {
return employee_id;
}
public void setEmployee_id(Integer employee_id) {
this.employee_id = employee_id;
}
public Integer getEquipment_id() {
return equipment_id;
}
public void setEquipment_id(Integer equipment_id) {
this.equipment_id = equipment_id;
}
#Column(name = "type")
private String type;
#Column(name = "date")
private String date;
#Column(name = "time")
private String time;
#Column(name = "employee_id")
private Integer employee_id;
#Column(name = "equipment_id")
private Integer equipment_id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "room_id", insertable = false, updatable = false)
#Fetch(FetchMode.JOIN)
private Tbl_Rooms thisroom;
public Tbl_Rooms getThisroom() {
return thisroom;
}
public void setThisroom(Tbl_Rooms thisroom) {
this.thisroom = thisroom;
}
public Tbl_Bookings() {
}
public Tbl_Bookings(String type, String date, String time, Integer employee_id, Integer equipment_id) {
this.type = type;
this.date = date;
this.time = time;
this.employee_id = employee_id;
this.equipment_id = equipment_id;
}
}
Tbl_Rooms Entity
package com.sam.ResourceBookingMS.model;
import java.io.Serializable;
import java.util.Set;
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.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name = "Tbl_Rooms")
public class Tbl_Rooms implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "room_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "name")
private String name;
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 String getCapacity() {
return capacity;
}
public void setCapacity(String capacity) {
this.capacity = capacity;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Column(name = "capacity")
private String capacity;
#Column(name = "location")
private String location;
#Column(name = "description")
private String description;
#OneToMany(targetEntity = Tbl_Bookings.class, mappedBy = "id", orphanRemoval = false, fetch = FetchType.LAZY)
private Set<Tbl_Bookings> bookings;
public Set<Tbl_Bookings> getBookings() {
return bookings;
}
public void setBookings(Set<Tbl_Bookings> bookings) {
this.bookings = bookings;
}
public Tbl_Rooms() {
}
public Tbl_Rooms(String name, String capacity, String location, String description) {
this.name = name;
this.capacity = capacity;
this.location = location;
this.description = description;
}
}
Controller
package com.sam.ResourceBookingMS;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.EntityManager;
import org.springframework.beans.factory.annotation.Autowired;
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.sam.ResourceBookingMS.model.Tbl_Bookings;
import com.sam.ResourceBookingMS.model.Tbl_Rooms;
#RestController
public class BookRmController {
#Autowired
private TblBkRepository tbr;
#Autowired
private TblRmRepository trr;
#Autowired
private EntityManager entityManager;
#RequestMapping(value = "/bookRm", method = RequestMethod.POST)
#ResponseBody
public String sendData(#RequestBody Tbl_Bookings bk) {
Tbl_Rooms rm = entityManager.getReference(Tbl_Rooms.class, 1);
System.out.println(rm.getId());
Tbl_Bookings booking = new Tbl_Bookings();
booking.setDate(bk.getDate());
booking.setType(bk.getType());
booking.setTime(bk.getTime());
Tbl_Rooms room = new Tbl_Rooms();
room.setCapacity(rm.getCapacity());
room.setDescription(rm.getDescription());
room.setLocation(rm.getLocation());
room.setName(rm.getName());
Set<Tbl_Bookings> bookingOfRoom = new HashSet<Tbl_Bookings>();
bookingOfRoom.add(booking);
room.setBookings(bookingOfRoom);
booking.setThisroom(room);
trr.save(room);
return "Confirmed";
}
}
This is the json data being sent to the controller.
{"room_id":2,"date":"2019-07-26","time":"10:00am to 10:30am","type":"Room"}

mappedBy in parent must be matched with a name defined in the child
(change id to thisroom)
case: "save Child with Parents ID" (might be above UseCase)
For that, we have to request the Child Entity with Parent ID (see JSON request at the controller and set the Parent for that Child) and using Child Repository save the object instead of using parent repository.
case: "save child-parent at same request"
For that, we have to request the Parent Entity which has multiple children (for OneToMany) and using for setting the childerns
Parent
#OneToMany(targetEntity = Tbl_Bookings.class, mappedBy = "thisroom", orphanRemoval = false, fetch = FetchType.LAZY, cascade=CascadeType.ALL)
private Set<Tbl_Bookings> bookings;
Child
#ManyToOne(cascade=CascadeType.ALL,fetch = FetchType.LAZY)
#JoinColumn(name = "room_id", insertable = false, updatable = false)
#Fetch(FetchMode.JOIN)
private Tbl_Rooms thisroom;
Parent-Child Relationship for referance
Parent.java
#Entity
#Table(name = "parent")
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#ToString
public class Parent {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int parentId;
private String name;
#OneToMany(mappedBy="parent",fetch=FetchType.LAZY,cascade = CascadeType.PERSIST)
private List<Child> child = new ArrayList<Child>();
}
Child.java
#Entity
#Table(name = "child")
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#ToString
public class Child {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int childId;
private String account;
#ManyToOne(fetch = FetchType.LAZY, targetEntity = Parent.class)
#JoinColumn(name="parentId", referencedColumnName = "parentId", nullable = false)
private Parent parent;
}
Controller
#RestController
public class RelationshipController {
#Autowired ParentRepository parentRepository;
#Autowired ChildRepository childRepository;
//save Child with Parent at same
#PostMapping(value = "/onetomany")
public String OneToMany(#RequestBody Parent parent)
{
for (Child child : parent.getChild()) {
child.setParent(parent);
}
parent.setChild(parent.getChild());
parentRepository.save(parent);
return "saved";
/*{
"name":"Romil",
"child":[
{"account":"1"},
{"account":"2"}
]
}*/
}
//save Child with Parent's ID
#PostMapping(value = "/onetomanyPID")
public String OneToMany(#RequestBody Child child)
{
child.setParent(child.getParent());;
childRepository.save(child);
return "saved";
/*{
"account":"3",
"parent":{
"parentId":"1",
"name":"Romil"
}
}*/
}
}
UPDATE
Controller
#PostMapping("/save")
public String save(#RequestBody Tbl_Bookings bookings)
{
bookings.setThisroom(bookings.getThisroom());
tbr.save(bookings);
return "Confirmed";
}
JSON
{
"thisroom":{
"id":"1"
},
"date":"2019-07-26",
"time":"10:00am to 10:30am",
"type":"Room"
}
Tbl_Bookings
#Entity
#Table(name = "Tbl_Bookings")
public class Tbl_Bookings implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "booking_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id", referencedColumnName = "room_id")
private Tbl_Rooms thisroom;
}
Tbl_Rooms
#Entity
#Table(name = "Tbl_Rooms")
public class Tbl_Rooms implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "room_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#OneToMany(targetEntity = Tbl_Bookings.class, mappedBy = "thisroom", orphanRemoval = false, fetch = FetchType.LAZY, cascade=CascadeType.ALL)
private List<Tbl_Bookings> bookings = new ArrayList<Tbl_Bookings>();
}

There are two points you made mistakes.
First) You need to change OneToMany relation in Tbl_Rooms class as below:
#OneToMany(targetEntity = Tbl_Bookings.class, mappedBy = "thisroom", orphanRemoval = false, fetch = FetchType.LAZY)
private Set<Tbl_Bookings> bookings;
The mappedBy attribute should be the class member of owner side.
Second) You create a new Tbl_Rooms instance in controller. So it is natural a new record would be created for rooms too.

Related

Passing JSON in body spring and constructing object with foreign key

I am trying to create a basic spring API.
I have a Post class that have an attribute User user as foreign key.
package com.example.demo.model;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import jakarta.persistence.*;
import java.util.Objects;
#Entity
public class Post {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(nullable = false, updatable = false)
private Long id;
private String title;
private String body;
#ManyToOne
private User user;
public Post() {
}
public Post(String title, String body) {
this.title = title;
this.body = body;
}
// Getters and Settes ...
}
Here is the User class
package com.example.demo.model;
import jakarta.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
#Entity
public class User implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(nullable = false, updatable = false)
private Long id;
private String name;
private Integer age;
private String email;
#OneToMany(mappedBy = "user")
private List<Post> posts = new ArrayList<Post>();
#ManyToMany
#JoinTable(name = "user_task",
joinColumns = #JoinColumn(name = "user_id"),
inverseJoinColumns = #JoinColumn(name = "task_id"))
private List<Task> tasks = new ArrayList<Task>();
public User() {}
public User(String name, Integer age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
// Getters and Settes ...
}
and here is my Post Controller
package com.example.demo.controller;
import com.example.demo.model.Post;
import com.example.demo.service.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
#RestController
#RequestMapping("/post")
public class PostController {
private final PostService postService;
#Autowired
public PostController(PostService postService) {
this.postService = postService;
}
#GetMapping("/all")
public List<Post> getAllPosts (){
System.out.println("3");
return postService.getAllPosts();
}
#GetMapping("/{id}")
public Post getPost(#PathVariable Long id){
System.out.println("2");
return postService.getPost(id);
}
#PostMapping("/create")
public Post createPost(#RequestBody Post post){
return postService.createPost(post);
}
}
So in the /create endpoint i am passing a json object in the body. Here is an exemple:
{
"title": "Post1",
"body": "Post1 Body",
"user": "1"
}
the user: 1 is the foreign key to user who owns the post.
Here is the full error:
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.example.demo.model.User` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('1')]
I need to insert the json object into the Post table with the foreign key

How to add the IDs of foreign tables to another table passing the parameters by constructor?

Hi everyone I'm working with SpringBoot and I want to send the ID's of table Producto and Cliente to Pedidos, I'm using the constructor for to pass of parametrs
I tried to create a List as String to hold the values ​​and then use it to send the data to the other method
Class Product
package com.example.demo.model;
import java.util.Set;
import javax.persistence.*;
#Entity
#Table(name = "Productos")
public class Producto {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String nombreProducto;
private String precioProducto;
/*Here i send of FK of this table to Pedidos*/
#OneToMany(mappedBy = "producto",cascade = CascadeType.ALL)
private Set<Pedido> pedidos;
public Producto(String nombreProducto, String precioProducto) {
this.nombreProducto = nombreProducto;
this.precioProducto = precioProducto;
}
//Getters and Setters
}
Class Cliente
package com.example.demo.model;
import java.util.Set;
import javax.persistence.*;
#Entity
#Table(name="Clientes")
public class Cliente {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String nombreCliente;
private String correoElectronico;
/*Here i send of FK of this table to Pedidos*/
#OneToMany(mappedBy = "cliente",cascade = CascadeType.ALL)
private Set<Pedido> pedidos;
public Cliente(String nombreCliente, String correoElectronico) {
this.nombreCliente = nombreCliente;
this.correoElectronico = correoElectronico;
}
//Getters and Setters
}
Class Pedido
package com.example.demo.model;
import javax.persistence.*;
#Entity
#Table(name = "Pedido")
public class Pedido {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String fechaPedido;
private String direccion;
/*
Here I create the atribute of FK of the tables Cliente and Producto
*/
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "cliente_id", referencedColumnName = "id")
private Cliente cliente;
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "producto_id", referencedColumnName = "id")
private Producto producto;
public Pedido(String fechaPedido, String direccion, Cliente cliente, Producto producto) {
this.fechaPedido = fechaPedido;
this.direccion = direccion;
this.cliente = cliente;
this.producto = producto;
}
//Getters and Setters
}
And the last Class it's the RunnClass
package com.example.demo;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
//import java.util.stream.Stream;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import com.example.demo.model.Cliente;
import com.example.demo.model.Pedido;
import com.example.demo.model.Producto;
import com.example.demo.repository.ClienteRepository;
import com.example.demo.repository.PedidosRepository;
import com.example.demo.repository.ProductoRepositroy;
import com.github.javafaker.Faker;
#Component
public class SampleDataLoader implements CommandLineRunner {
private final ClienteRepository clienteRepository;
private final ProductoRepositroy productoRepositroy;
private final PedidosRepository pedidosRepository;
private final Faker faker; //It's a ASI of DataFaker
public SampleDataLoader(ClienteRepository clienteRepository,
ProductoRepositroy productoRepositroy,
PedidosRepository pedioPedidosRepository) {
this.clienteRepository = clienteRepository;
this.productoRepositroy = productoRepositroy;
this.pedidosRepository = pedioPedidosRepository;
this.faker = new Faker(); //It's a ASI of DataFaker
}
#Override
public void run(String... args) throws Exception {
ejecutarClases();
}
private void ejecutarClases() {
List<Cliente> clientes = IntStream.rangeClosed(1, 20)
.mapToObj(i -> new Cliente(faker.name().fullName(),
faker.internet().emailAddress()))
.collect(Collectors.toList());
clienteRepository.saveAll(clientes);
List<Producto> productos = IntStream.rangeClosed(1, 100)
.mapToObj(i -> new Producto(faker.commerce().productName(), "$"+faker.commerce().price()))
.collect(Collectors.toList());
productoRepositroy.saveAll(productos);
//I don't know how to send two ID's to this table,
//if you can see I have two values as null
//I want to send the ID's the other tables
List<Pedido> pedidos = IntStream.rangeClosed(1, 30)
.mapToObj(i -> new Pedido(faker.backToTheFuture().date(),
faker.address().streetAddress(), null, null))
.collect(Collectors.toList());
pedidosRepository.saveAll(pedidos);
}
}
I hope someone can help me please.

Spring Boot Rest API Issues

I'm trying to implement a Spring Boot Rest API using Spring Data Jdbc with H2 Database.
This is a microservice, and I'm trying to send a POST request to the microservice from an angular app. I know my POST is working correctly from Angular. Inside of microservice, I am trying to save the POST request to a local H2 database.
This should be relatively straight forward based on documentation I've read online, but I am getting error messages. Any help would be greatly appreciated. Here are the files I have setup inside my spring boot microservice (titled 'order'):
OrderController.java:
package com.clothingfly.order;
import java.util.ListIterator;
import org.springframework.web.client.RestTemplate;
import com.clothingfly.order.Model.Item;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.clothingfly.order.Model.Order;
#RestController
#CrossOrigin(origins = "http://localhost:4200")
public class OrderController {
#Autowired
TempOrderRepository orderRepository;
#PostMapping("/order")
public Order postOrder(#RequestBody Order order) {
Order _order = orderRepository.save(new Order(order.getId(), order.getAddress(), order.getPayment(), order.getItems()));
return _order;
}
}
TempOrderRepository.java:
package com.clothingfly.order;
import org.springframework.data.jpa.repository.JpaRepository;
import com.clothingfly.order.Model.Order;
public interface TempOrderRepository extends JpaRepository<Order, Long>{
}
OrderApplication.java:
package com.clothingfly.order;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
And I have a model named Order.java:
package com.clothingfly.order.Model;
import java.util.List;
import javax.persistence.*;
import org.springframework.data.annotation.Id;
#Entity
#Table(name = "orders")
public class Order {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(name = "Address")
private Address address;
#Column(name = "Payment")
private PaymentInfo payment;
#Column(name = "Items")
private List<Item> items;
#Column(name = "Error")
private String error;
public Order() {
}
public Order(long id, Address address, PaymentInfo payment, List<Item> items){
this.id = id;
this.address = address;
this.payment = payment;
this.items = items;
this.error = "";
}
public long getId() {
return id;
}
public Address getAddress() {
return address;
}
public PaymentInfo getPayment() {
return payment;
}
public List<Item> getItems() {
return items;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
}
The Order model takes in three other models:
Item.java:
package com.clothingfly.order.Model;
import javax.persistence.*;
#Entity
#Table(name = "items")
public class Item {
#Id
#GeneratedValue
#Column(name = "id")
private long id;
#Column(name = "name")
private String name;
#Column(name = "price")
private float price;
#Column(name = "imageUrl")
private String imageUrl;
#Column(name = "quantity")
private long quantity;
#Column(name = "inventory")
private long inventory;
public long getId() {
return id;
}
public String getName() {
return name;
}
public float getPrice() {
return price;
}
public long getQuantity() {
return quantity;
}
public long getInventory() {
return inventory;
}
public String getImageUrl(){
return imageUrl;
}
public void setInventory(long inventory) {
this.inventory = inventory;
}
public void setName(String name) {
this.name = name;
}
public void setPrice(float price) {
this.price = price;
}
public void setQuantity(long quantity) {
this.quantity = quantity;
}
public Item(long id, String name, float price, long quantity, long inventory, String imageUrl) {
this.id = id;
this.name = name;
this.price = price;
this.quantity = quantity;
this.inventory = inventory;
this.imageUrl = imageUrl;
}
public Item() {
}
}
Address.java:
package com.clothingfly.order.Model;
import javax.persistence.*;
#Entity
#Table(name = "addresses")
public class Address {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(name = "firstName")
private String firstName;
#Column(name = "lastName")
private String lastName;
#Column(name = "address")
private String address;
#Column(name = "country")
private String country;
#Column(name = "apartmentNo")
private String apartmentNo;
#Column(name = "state")
private String state;
#Column(name = "city")
private String city;
#Column(name = "zipcode")
private String zipcode;
public Address() {
}
public Address(String firstName, String lastName, String address, String country, String apartmentNo, String state,
String city, String zipcode) {
this.firstName = firstName;
this.lastName = lastName;
this.address = address;
this.country = country;
this.apartmentNo = apartmentNo;
this.state = state;
this.city = city;
this.zipcode = zipcode;
}
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 getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getApartmentNo() {
return apartmentNo;
}
public void setApartmentNo(String apartmentNo) {
this.apartmentNo = apartmentNo;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
}
PaymentInfo.java:
package com.clothingfly.order.Model;
import javax.persistence.*;
#Entity
#Table(name = "payments")
public class PaymentInfo {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
#Column(name = "cardHolder")
private String cardHolder;
#Column(name = "cardNumber")
private String cardNumber;
#Column(name = "expirationDate")
private String expirationDate;
#Column(name = "cvv")
private String cvv;
public PaymentInfo(String cardHolder, String cardNumber, String expirationDate, String cvv) {
this.cardHolder = cardHolder;
this.cardNumber = cardNumber;
this.expirationDate = expirationDate;
this.cvv = cvv;
}
public String getCardHolder() {
return cardHolder;
}
public void setCardHolder(String cardHolder) {
this.cardHolder = cardHolder;
}
public String getCardNumber() {
return cardNumber;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
public String getExpirationDate() {
return expirationDate;
}
public void setExpirationDate(String expirationDate) {
this.expirationDate = expirationDate;
}
public String getCvv() {
return cvv;
}
public void setCvv(String cvv) {
this.cvv = cvv;
}
}
I'm getting the following error when trying to run microservice:
Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: com.clothingfly.order.Model.Address, at table: orders, for columns: [org.hibernate.mapping.Column(address)]
How would I go about fixing this?
I want to be able to display all of my models inside a table.
I tried changing Address model so that it only returns a string of the city, but that seemed to cause more issues than anything.
Note, one to one will always cause you an issue, always better to implement many to one and one to many. and add it to both entities you are mapping. It will do the same job with no errors.
First, create packages, and don't place everything in one package.
create
package com.clothingfly.repo or com.clothingfly.order.repo
package com.clothingfly.controller or com.clothingfly.order.controller
Secondly, add the annotation #Repository to your repository interface
package com.clothingfly.repo;
import org.springframework.data.jpa.repository.JpaRepository;
import com.clothingfly.order.Model.Order;
#Repository
public interface TempOrderRepository extends JpaRepository<Order, Long>{
}
Thirdly, add the annotation #EnableJpaRepositories(basePackages = "com.clothingfly.repo") to your main application class.
package com.clothingfly.order;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
#EnableJpaRepositories(basePackages = "com.clothingfly.repo")
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
Lastly, this will not work correctly. Not sure what you are doing here.
#Column(name = "Address")
private Address address;
Try this:
add this in your address entity
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name="order_id", nullable = false)// add this column
// order_id in your Address database not the entity
#OnDelete(action = OnDeleteAction.CASCADE)
#JsonIgnore
private Order order;
Then, add this to your Order class.
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="order")
#OnDelete(action = OnDeleteAction.CASCADE)
#JsonIgnore
List<Address> address = new ArrayList<Address>(); // I use list cause sometimes it throws an error
// try to simply use this, if it throws expection then use the list
//private Address address;
Your Order constructor should be like:
public Order(long id, List<Address> address ...etc
Or simply
public Order(long id, Address address ...etc
Do this for all your mapped entities and don't forget to add setters and getters for all fields.
you have to tell hibernate that the Address object is coming from another table and how to join those tables, since your orders table most likely does not have a column which contains the hole address but the the address id/ primary key of the address as foreign key.
this is possible, depending if you have 1:1, 1:n, n:1 or n:m relations with the corresponding #OneToOne, #OneToMany, #ManyToOne and #ManyToMany annotations.
for your example it could be something like
#OneToOne
#JoinColumn(name = "address_id", referencedColumnName = "id")
private Address address;

problem with saving data in many-to-many intermediate table spring boot

following are my entity
package bt.gov.dit.inventoryservice.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
//import org.hibernate.mapping.Set;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
#Entity
#Table(name = "items")
public class Items implements Serializable {
private Long Id;
#Column(name = "item_name")
private String itemName;
// #ManyToOne(fetch = FetchType.LAZY)
// #JoinColumn(name = "categories_id",nullable = false, referencedColumnName = "id")
private Categories categories;
private Stores stores;
//#Temporal(TemporalType.TIMESTAMP)
#Column(name = "insert_date")
private Date insertDate = new Date();
// #Temporal(TemporalType.TIMESTAMP)
#Column(name = "update_date")
private Date updateDate = new Date();
private Set<Logs> logs = new HashSet<Logs>() ;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public Long getId() {
return Id;
}
public void setId(Long id) {
Id = id;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "categories_id", nullable = false, referencedColumnName = "id")
public Categories getCategories() {
return categories;
}
public void setCategories(Categories categories) {
this.categories = categories;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "stores_id", nullable = false, referencedColumnName = "id")
public Stores getStores() {
return stores;
}
public void setStores(Stores stores) {
this.stores = stores;
}
public Date getInsertDate() {
return insertDate;
}
public void setInsertDate(Date insertDate) {
this.insertDate = insertDate;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "items_logs", joinColumns = #JoinColumn(name = "items_id", referencedColumnName = "id"), inverseJoinColumns = #JoinColumn(name = "logs_id",referencedColumnName = "id") )
public Set<Logs> getLogs() {
return logs;
}
public void setLogs(Set<Logs> logs) {
this.logs = logs;
}
}
package bt.gov.dit.inventoryservice.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
#Entity
#Table(name = "logs")
public class Logs {
private Long id;
#Column(name = "cadet_id")
private Long cadetId;
private Set<Items> items = new HashSet<Items>() ;
#Column(name = "borrowed_date")
//#Temporal(TemporalType.TIMESTAMP)
private Date borrowedDate = new Date();
private String status;
private String comments;
#Id
#GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getCadetId() {
return cadetId;
}
public void setCadetId(Long cadetId) {
this.cadetId = cadetId;
}
public Date getBorrowedDate() {
return borrowedDate;
}
public void setBorrowedDate(Date borrowedDate) {
this.borrowedDate = borrowedDate;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
#ManyToMany(fetch = FetchType.LAZY,mappedBy = "logs")
public Set<Items> getItems() {
return items;
}
public void setItems(Set<Items> items) {
this.items = items;
}
}
I have many to many relationship between them. Due to that there is an intermediate table created with field item_id and log_id. Now I don't know how to save data in that table. I can save items and i can save log. But I have problem with saving the many-to-many relationship between them?

Spring (Hibernate) - incomplete serialization result / many-to-many

Rest Application / Spring MVC - 3 entities: User, AccessRole, AccessPermision.
Each user has only one role, each role has one or more privileges.
The problem occurs during serialization of users with the same role.
In such case, the JSON serialization result, contains permissions only for the first user.
User Entity
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import socialcreek.access.model.AccessRole;
import socialcreek.user.views.UserViews;
import javax.persistence.*;
import java.util.Set;
#Entity
#Table(name = "users")
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property = "id")
public class User {
/**-----------------------------------------------------
* Constructor
-------------------------------------------------------*/
public User(){ }
public User(String username, String password, AccessRole accessRole) {
this.username = username;
this.password = password;
this.userAccessRole = accessRole;
}
/**-----------------------------------------------------
* Entity Properties
-------------------------------------------------------*/
#Column()
#Id
#JsonView(UserViews.BasicView.class)
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#JsonView(UserViews.BasicView.class)
private String username;
private String password;
#JsonView(UserViews.BasicView.class)
#ManyToMany(mappedBy = "users",fetch=FetchType.EAGER)
private Set<UsersGroup> usersGroups;
#ManyToOne(targetEntity = AccessRole.class, optional = false,fetch = FetchType.EAGER, cascade=CascadeType.MERGE)
#JoinColumn(name = "user_role")
#JsonView(UserViews.BasicView.class)
private AccessRole userAccessRole;
/**-----------------------------------------------------
* Setters & Getters
-------------------------------------------------------*/
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<UsersGroup> getUsersGroups() {
return usersGroups;
}
public void setUsersGroups(Set<UsersGroup> usersGroups) {
this.usersGroups = usersGroups;
}
public AccessRole getUserAccessRole() {
return userAccessRole;
}
public void setUserAccessRole(AccessRole userAccessRole) {
this.userAccessRole = userAccessRole;
}
}
AccessRole Entity
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import socialcreek.user.views.UserViews;
import javax.persistence.*;
import java.util.Set;
#Entity
#Table(name = "access_role")
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property = "id")
public class AccessRole {
/**-----------------------------------------------------
* Entity Properties
-------------------------------------------------------*/
#Id
#JsonView(UserViews.BasicView.class)
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#JsonView(UserViews.BasicView.class)
private String roleName;
#JsonView(UserViews.BasicView.class)
#ManyToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
#JoinTable(name = "access_role_permissions")
private Set<AccessPermission> accessPermissions;
/**-----------------------------------------------------
* Setters & Getters
-------------------------------------------------------*/
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public Set<AccessPermission> getAccessPermissions() {
return accessPermissions;
}
public void setAccessPermissions(Set<AccessPermission> accessPermissions) {
this.accessPermissions = accessPermissions;
}
}
AccessPermission Entity
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import socialcreek.user.views.UserViews;
import javax.persistence.*;
#Entity
#Table(name = "access_permission")
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property = "id")
public class AccessPermission {
/**-----------------------------------------------------
* Entity Properties
-------------------------------------------------------*/
#Id
#JsonView(UserViews.BasicView.class)
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#JsonView(UserViews.BasicView.class)
private String permissionName;
/**-----------------------------------------------------
* Setters & Getters
-------------------------------------------------------*/
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPermissionName() {
return permissionName;
}
public void setPermissionName(String permissionName) {
this.permissionName = permissionName;
}
}
Serialization Result:
[ { "id":70, "username":"admin", "usersGroups":[], "userAccessRole":{
"id":68, "roleName":"ROLE_ADMIN", "accessPermissions":[
{
"id":69,
"permissionName":"FULL_ACCESS"
}]} },
{ "id":71, "username":"admin2", "usersGroups":[], "userAccessRole":68}
]
Please, have a look at accessRole and accessPermision information - it's complete only for the user:admin. In case of user:admin2 there is only information about accessRoleId ( no information about roleName, accessPermision)
It happens only when both users have the same accessRole. If I change accessRole of user:admin2 to another role - everythnink will be ok.
I found the similar issue with the correct answer (https://stackoverflow.com/a/27117097/4694022).
The problem is caused by #JsonIdentityInfo. After I removed it - it works ...now I need to find the solution to handle serialization for recursive structure but it's another story ...

Resources