Spring Boot Hibernate ManyToMany Relation using embedded model - mysql

I have a question about ManyToMany realation. Let's assume we have two model domains like Menu and RoleGroup,my Menu model includes a field named ' private RoleGroup roleGroup ' with #ManyToMany relation and #JoinTable with JoinColumns and InverseJoinColumns.
Imagine I already created an object like Menu that includes RoleGroup field with entityRepository .save in my database Here is my question, is there any way to update my object (considering to ManyToMany relation) without using native query? because when we use ManyToMany relationship hibernate handles it by creating third table like "Menu_RoleGroup" in database where as we don't have a domain like Menu_RoleGroup .
//Here is my application
package org.sayar.layout.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.Nationalized;
import org.sayar.layout.base.general.domain.GeneralDomain;
import org.sayar.layout.constants.SchemaList;
import org.sayar.layout.domain.uaa.Role;
import org.sayar.layout.domain.uaa.RoleGroup;
import org.springframework.data.annotation.Transient;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* This domain for store and transfer Menu
*
* #author Ehsan
*/
#Setter
#Getter
#AllArgsConstructor
#NoArgsConstructor
#JsonInclude(JsonInclude.Include.NON_NULL)
#Entity(name = Menu.TABLE_NAME)
#Table(name = Menu.TABLE_NAME, schema = SchemaList.LAYOUT)
public class Menu extends GeneralDomain {
#Transient
public final static String TABLE_NAME = "Menu";
public class CN {
public final static String title = "title";
public final static String description = "description";
public final static String banner = "banner";
}
#Nationalized
#Column(name = CN.title, length = 128, nullable = false)
private String title;
#Nationalized
#Column(name = CN.description, length = 1000)
private String description;
#Nationalized
#Column(name = CN.banner, length = 128)
private String banner;
/* Relationships */
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "Menu_RoleGroup",
schema = SchemaList.LAYOUT,
joinColumns = #JoinColumn(name = "menuId", referencedColumnName = GCN.id), //
inverseJoinColumns = #JoinColumn(name = "roleGroupId", referencedColumnName = GCN.id))
private Set<RoleGroup> roleGroupSet;
#OneToMany(mappedBy = MenuItem.CN.menu, fetch = FetchType.EAGER)
#JsonManagedReference
private Set<MenuItem> menuItemSet = new HashSet<>();
/* Constructors */
public Menu(String title, String banner, String description) {
this.title = title;
this.banner = banner;
this.description = description;
}
public Menu(String title, String banner, String description, Set<RoleGroup> roleGroupSet) {
this.title = title;
this.banner = banner;
this.description = description;
this.roleGroupSet = roleGroupSet;
}
public Menu(String id) {
super(id);
}
/* Other classes or enumerations */
}
.
.
.
.
.
package org.sayar.layout.domain.uaa;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Table;
import org.hibernate.annotations.Nationalized;
import org.sayar.layout.base.general.domain.GeneralDomain;
import org.sayar.layout.constants.SchemaList;
import org.springframework.data.annotation.Transient;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* This domain for store and transfer RoleGroup
*
* #author Ehsan
*
*/
#Setter
#Getter
#AllArgsConstructor
#NoArgsConstructor
#JsonInclude(JsonInclude.Include.NON_NULL)
#Entity(name = RoleGroup.TABLE_NAME)
#Table(name = RoleGroup.TABLE_NAME, schema = SchemaList.UAA)
public class RoleGroup extends GeneralDomain {
#Transient
public final static String TABLE_NAME = "RoleGroup";
public class CN {
public final static String title = "title";
public final static String status = "status";
}
#Nationalized
#Column(name = CN.title, length = 128, nullable = false)
private String title;
#Enumerated(EnumType.STRING)
#Column(name = CN.status, nullable = false)
private Status status;
public RoleGroup(String id) {
super(id);
}
/* Relationships */
/* Constructors */
/* Other classes or enumerations */
public enum Status {
ACTIVE, DE_ACTIVE
}
}
.
.
.
package org.sayar.layout.service.menu;
import org.sayar.layout.base.util.Print;
import org.sayar.layout.domain.Menu;
import org.sayar.layout.repository.megaitem.MegaItemRepository;
import org.sayar.layout.repository.menu.MenuRepository;
import org.sayar.layout.repository.menuitem.MenuItemRepository;
import org.sayar.layout.rest.menu.dto.*;
import org.springframework.stereotype.Service;
import org.sayar.layout.dao.menu.MenuDaoImpl;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import reactor.core.publisher.Mono;
/**
* Spring service implementation for the Menu entity.
*
* #author Ehsan
*/
#Service
#RequiredArgsConstructor
public class MenuServiceImpl implements MenuService {
private final MenuDaoImpl entityDao;
private final MenuRepository entityRepository;
private final MenuItemRepository menuItemRepository;
private final MegaItemRepository megaItemRepository;
#Override
public Mono<ResponseEntity<Boolean>> create(ReqMenuCreateDTO entity, String userId) {
return Mono.just(entityRepository.save(entity.map(userId)))
.flatMap(createdEntity -> Mono.just(ResponseEntity.ok().body(true))
)
.defaultIfEmpty(ResponseEntity.ok().body(false));
}
#Transactional
#Override
public Mono<ResponseEntity<Boolean>> update(String id, ReqMenuUpdateDTO entity) {
Mono.just(entityRepository.update(id, entity.getTitle(), entity.getBanner(), entity.getDescription())).subscribe();
Mono.just(entityRepository.deleteRoleMenu(id)).subscribe();
Print.print("title", entity);
if (entity.getRoleGroupIdSet() != null && !entity.getRoleGroupIdSet().isEmpty())
for (String roleId : entity.getRoleGroupIdSet()) {
Mono.just(entityRepository.updateRoleMenu(id, roleId)).subscribe();
}
return Mono.just(ResponseEntity.ok().body(true));
}
.
.
.
.
.
package org.sayar.layout.repository.menu;
import org.sayar.layout.constants.SchemaList;
import org.sayar.layout.repository.menu.dto.ResRoleGetListRepoDTO;
import org.sayar.layout.rest.menu.dto.ResMenuGetListDTO;
import org.sayar.layout.repository.menu.dto.ResMenuGetOneRepoDTO;
import org.sayar.layout.rest.menu.dto.ResMenuGetOneDTO;
import org.sayar.layout.rest.menu.dto.ResMenuGetPageDTO;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
import org.sayar.layout.domain.Menu;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
/**
* Spring Data SQL Server repository for the Menu entity.
*
* #author Ehsan
*/
#Repository
public interface MenuRepository extends JpaRepository<Menu, String> {
// UPDATE ALL STARTS HERE
#Transactional
#Modifying
#Query(value = "UPDATE Menu AS m SET m.title = :title , m.description = :description, m.banner = :banner WHERE m.id = :id")
Integer update(#Param("id") String id, #Param("title") String title, #Param("description") String description, #Param("banner") String banner);
#Transactional
#Modifying
#Query(value = "DELETE FROM layout.Menu_RoleGroup WHERE menuId = :id", nativeQuery = true)
Integer deleteRoleMenu(#Param("id") String id);
#Transactional
#Modifying
#Query(value = "INSERT INTO layout.Menu_RoleGroup (menuId,roleGroupId) VALUES (:menuId,:roleGroupId)", nativeQuery = true)
Integer updateRoleMenu(#Param("menuId") String menuId, #Param("roleGroupId") String roleGroupId);
}

Actually I find out how to solve it!
In this case I have to create a domain model like MenuRoleGroup as an Entity and then add an Embeddable field e.g MenuRoleGroupEmbeddable and use create #EmbeddedId field within MenuRoleGroup.
then add the primary key of Menu and RoleGroup within MenuRoleGroupEmbeddable.
so Spring Data is able to create MenuRoleGroupRepository that extends JPA Repository and but notice that this table has two primary keys not one.
notice that MenuRoleGroupEmbeddable field within MenuRoleGroup doesn't has relationship but Menu and RoleGroup both have #ManyToOne relation with MenuRoleGroupEmbeddable model.
here is the example.
package org.sayar.wms.domain.Menu;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.GenericGenerator;
import org.sayar.wms.base.general.domain.GeneralDomain;
import org.sayar.wms.constants.SchemaList;
import org.sayar.wms.domain.container.Container;
import org.sayar.wms.domain.product.ProductContainerEmbeddable;
import org.springframework.data.annotation.Transient;
import javax.persistence.*;
import java.util.Date;
#Setter
#Getter
#AllArgsConstructor
#NoArgsConstructor
#JsonInclude(JsonInclude.Include.NON_NULL)
#Entity(name = MenuRoleGroup.TABLE_NAME)
#Table(name = MenuRoleGroup.TABLE_NAME, schema = SchemaList.WMS)
public class MenuRoleGroup {
#Transient
public final static String TABLE_NAME = "MenuRoleGroup";
public class CN {
public final static String startDate = "startDate";
}
#EmbeddedId
private MenuRoleGroupEmbeddable menuRoleGroupEmbeddable;
#JoinColumn(name = CN.startDate, referencedColumnName = GeneralDomain.GCN.id)
private Date startDate;
}
package org.sayar.wms.domain.Menu;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.sayar.wms.base.general.domain.GeneralDomain;
import org.sayar.wms.domain.container.Container;
import javax.persistence.CascadeType;
import javax.persistence.Embeddable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import java.io.Serializable;
import java.util.Set;
/**
* This domain for store and transfer Warehouse
*
* #author masoud
*/
#Setter
#Getter
#AllArgsConstructor
#NoArgsConstructor
#JsonInclude(JsonInclude.Include.NON_NULL)
#Embeddable
public class ProductContainerEmbeddable implements Serializable {
public class CN {
public final static String menuId = "menuId";
public final static String roleGroupId = "roleGroupId";
}
/* Relationships */
#ManyToOne
#JoinColumn(name = CN.menu, referencedColumnName = "id")
private Menu menu;
#ManyToOne
#JoinColumn(name = CN.roleGroup, referencedColumnName ="id")
private RoleGroup roleGroup;
/* Constructors */
/* Other classes or enumerations */
}
menuId and roleGroupId are both primary keys of hte MenuRoleGroup entity.

Related

How to delete/update by querying on JPA interface?

The Item table has Many to One relationship with supplier table.
If i delete supplier table row data by Id, its not deleting the row.
The Item table has many rows with same supplier Id. If i delete in supplier table with id, the item table supplier column data /id should be deleted.
Thanks in advance
Item
package com.ingroinfo.ubm.entity;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
#Entity
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Table(name = "master_item")
#SequenceGenerator(name = "item_sequence", initialValue = 201, allocationSize = 10000)
public class Item {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "branch_sequence")
private Long itemId;
private String itemName;
private String itemImage;
private String itemStatus;
private String unitOfMeasure;
private String remarks;
private String units;
#ManyToOne
#JoinColumn(name = "category_id")
private Category category;
#ManyToOne
#JoinColumn(name = "supplier_id")
private Supplier supplier;
#ManyToOne
#JoinColumn(name = "brand_id")
private Brand brand;
#ManyToOne
#JoinColumn(name = "publisher_id")
private BrandPublisher publisher;
#ManyToOne
#JoinColumn(name = "hsn_id")
private HsnCode hsnCode;
#Column(name = "date_created")
#CreationTimestamp
private Date dateCreated;
#Column(name = "last_updated")
#UpdateTimestamp
private Date lastUpdated;
}
ItemRepository
package com.ingroinfo.ubm.dao;
import javax.transaction.Transactional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import com.ingroinfo.ubm.entity.Item;
#Repository
#Transactional
public interface ItemRepository extends JpaRepository<Item, Long> {
Item findByItemId(Long id);
#Modifying
#Query("UPDATE Item i SET i.supplier= :val WHERE i.supplier = :id")
void deleteSupplierId(#Param("val") String val, #Param("id") Long id);
}
MasterService
void deleteItemSupplierId(String val, Long id);
MasterServiceImpl
#Override
public void deleteItemSupplierId(String val, Long id) {
itemRepository.deleteSupplierId(val, id);
}
MasterController
#GetMapping("/supplier/delete")
public String deleteSupplier(#RequestParam Long supplierId) {
masterService.deleteItemSupplierId(null, supplierId);
masterService.deleteBySupplierId(supplierId);
return "redirect:/master/supplier/list?supplierDeleted";
}
You can do that by using cascade types, for example
#OneToMany(cascade = CascadeType.REMOVE)

Why does my method with #Query to perform a PostMapping or save me generate an error type: java.sql.SQLException: Not a navigable ResultSet

I am trying to perform a CRUD with JPA and mysql through #Query, for this in my database I have a stored procedure that registers me in a table.
When I hit the service from the postman, it generates a 500 Internal Server Error and in the console of my IDEA it responds with the error:
java.sql.SQLException: Create breakpoint Not a navigable ResultSet.
I leave here the complete flow of what I am doing, from the database to the controller
CREATE DEFINER=`root`#`localhost` PROCEDURE `insert_ticket_procedure`( IN codigo VARCHAR(45),
IN user_id int,
IN cost float,
IN seats_amount int,
IN laggage_amount int,
IN total_seats_amount int,
IN driver_id int
)
BEGIN
INSERT INTO tickets (code, user_id, cost, seats_amount, laggage_amount, total_seats_amount, driver_id)
values(codigo, user_id, cost, seats_amount, laggage_amount, total_seats_amount, driver_id );
END
In my application I have two DTOs:
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Getter
#Setter
#Entity
public class Tickets{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer ticket_id;
private String code;
private Integer driver_id;
private Integer user_id;
private Float cost;
private Integer seats_amount;
private Integer laggage_amount;
private Integer total_seats_amount;
}
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.util.List;
#Getter
#Setter
#Entity
public class Users {
#Id
private Integer user_id;
private String complete_name;
private String mail;
private String password;
private String number;
#OneToMany(cascade={CascadeType.ALL})
#JoinColumn(name="user_id")
private List<Tickets> ticketsList;
}
The relationship is that a user can have many tickets
import com.terminals.demo.dto.Tickets;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
#Repository
public interface TicketsRepository extends JpaRepository<Tickets, Integer> {
#Query(value = "{call insert_ticket_procedure(:code, :driver_id, :user_id, :cost, :seats_amount, :laggage_amount, :total_seats_amount)}", nativeQuery = true)
void insertTickets(
#Param("code")String code,
#Param("driver_id")Integer driver_id,
#Param("user_id")Integer user_id,
#Param("cost")Float cost,
#Param("seats_amount")Integer seats_amount,
#Param("laggage_amount")Integer laggage_amount,
#Param("total_seats_amount")Integer total_seats_amount
);
}
This repository is called by a implementation or "service" that implements an interface
import com.terminals.demo.Repository.TicketsRepository;
import com.terminals.demo.dto.Tickets;
import com.terminals.demo.interfaces.ITickersImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class TicketsImpl implements ITickersImpl {
#Autowired
private TicketsRepository ticketsRepository;
#Override
public void saveTickets(Tickets tickets) {
ticketsRepository.insertTickets(tickets.getCode(),tickets.getDriver_id(),tickets.getUser_id(), tickets.getCost(),tickets.getSeats_amount(), tickets.getLaggage_amount(),tickets.getTotal_seats_amount());
}
}
And the controller:
import com.terminals.demo.dto.Tickets;
import com.terminals.demo.interfaces.ITickersImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("/terminals")
public class TicketsController {
#Autowired
ITickersImpl iTickers;
#PostMapping("/addticket")
public ResponseEntity<?> insertTicket(#RequestBody Tickets tickets){
iTickers.saveTickets(tickets);
return new ResponseEntity<>("Registro Exitoso", HttpStatus.CREATED);
}
}
My request:
"code": "sdf23f",
"driver_id": 1,
"user_id": 2,
"cost": 23.0,
"seats_amount": 20,
"laggage_amount": 2,
"total_seats_amount": 2
}```

Need to get Spring to return MySQL View data back to REACT front end

I am trying to get my Spring MySQL backend to return a mutli table VIEW (not a single table) thru AXIOS to my REACT front end.
I am testing my Backend with POSTMAN (http://localhost:8080/api/v1/cpysiteassetview)
I get an error messages from SPRING and a long error message from POSTMAN (below).
I am close, but going wrong somewhere and I hope someone more familiar with this can shed some light and explain where I am going wrong.
Here is the VIEW\MODEL\REPOSITORY\CONTROLLER.
...
CREATE
ALGORITHM = UNDEFINED
DEFINER = `root`#`localhost`
SQL SECURITY DEFINER
VIEW `cpysiteasset` AS
SELECT
`cpymaster`.`cpymasterid` AS `cpymasterid`,
`cpymaster`.`cpymastercode` AS `cpymastercode`,
`cpymaster`.`cpymastername` AS `cpymastername`,
`sitemaster`.`sitemasterid` AS `sitemasterid`,
`sitemaster`.`sitemastercode` AS `sitemastercode`,
`sitemaster`.`sitemastername` AS `sitemastername`,
`assets`.`assetsid` AS `assetsid`,
`assets`.`assetsidentifier` AS `assetsidentifier`,
`assets`.`assetsname` AS `assetsname`
FROM
((`cpymaster`
JOIN `sitemaster` ON = `cpymaster`.`cpymasterid`)))
JOIN `assets` ON ((`assets`.`sitemaster_sitemasterid` = `sitemaster`.`sitemasterid`)))
ORDER BY `sitemaster`.`sitemastercode` , `assets`.`assetsidentifier`
//MODEL
package net.javaguides.springboot.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;
import org.hibernate.annotations.Immutable;
#Entity
#Immutable
#Table(name = "`cpysiteassetview`")
public class CpySiteAssetView {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private int cpymasterid;
private String cpymastercode;
private String cpymastername;
private int sitemasterid;
private String sitemastercode;
private String sitemastername;
private int assetsid;
private String assetsidentifier;
private String assetsname;
#Column(name = "cpymasterid")
public int getCpymasterid() {
return cpymasterid;
}
#Column(name = "cpymastercode")
public String getCpymastercode() {
return cpymastercode;
}
#Column(name = "cpymastername")
public String getCpymastername() {
return cpymastername;
}
#Column(name = "sitemasterid")
public int getSitemasterid() {
return sitemasterid;
}
#Column(name = "sitemastercode")
public String getSitemastercode() {
return sitemastercode;
}
#Column(name = "sitemastername")
public String getSitemastername() {
return sitemastername;
}
#Column(name = "assetsid")
public int getAssetsid() {
return assetsid;
}
#Column(name = "assetsidentifier")
public String getAssetsidentifier() {
return assetsidentifier;
}
#Column(name = "assetsname")
public String getAssetsname() {
return assetsname;
}
}
//Repository
package net.javaguides.springboot.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import net.javaguides.springboot.model.CpySiteAssetView;
#Repository
public interface CpySiteAssetViewRepository1 extends JpaRepository<CpySiteAssetView, Long>{
public List<CpySiteAssetView> findAll();
}
//Controller
package net.javaguides.springboot.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import net.javaguides.springboot.model.CpySiteAssetView;
import net.javaguides.springboot.repository.CpySiteAssetViewRepository1;
#CrossOrigin(origins = "http://localhost:3000")
#RestController
#RequestMapping("/api/v1/")
public class CpySiteAssetViewController {
#Autowired
private CpySiteAssetViewRepository1 cpySiteAssetViewRepository1;
//get all
#GetMapping("/cpysiteassetview")
public List<CpySiteAssetView> getAllCpySiteAssetView(){
return cpySiteAssetViewRepository1.findAll();
}
}
...
Error Message from Spring:
java.sql.SQLSyntaxErrorException: Unknown column 'cpysiteass0_.id' in 'field list'
Error Message from Postman (first part):
"error": "Internal Server Error",
"trace": "org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet\r\n\tat org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:259)\r\n\tat org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233)\r\n\tat org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:551)\r\n\tat org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)\r\n\tat org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)\r\n\tat org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(Per
OK..commented out //private long id;
and now it works !!!!!

Spring - can't save an entity with CRUD Repository

I am making simple program that have to get some info from OpenWeatherMap API and save it in MySQL database:
package com.example.restTemplate;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
#SpringBootApplication
public class RestTemplateApplication {
public static void main(String[] args) {
SpringApplication.run(RestTemplateApplication.class, args);
}
#Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
package com.example.restTemplate.Model;
import lombok.*;
import javax.persistence.Entity;
import javax.persistence.Id;
#NoArgsConstructor
#AllArgsConstructor
#Entity
#javax.persistence.Table(name="Weather")
#Getter
#Setter
#ToString
public class WeatherScore {
#Id
private int id;
private String city;
private double temperature;
private int pressure;
private long currentDate;
}
package com.example.restTemplate.Controller;
import com.example.restTemplate.Model.WeatherScore;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface WeatherCRUDRepository
extends CrudRepository<WeatherScore, Long> {
WeatherScore save (WeatherScore score);
}
package com.example.restTemplate.Controller;
import com.example.restTemplate.Model.WeatherScore;
import org.springframework.context.ApplicationContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
import java.util.Random;
#RestController
public class ConsumeWebService {
#Autowired
RestTemplate restTemplate;
WeatherCRUDRepository repository;
ApplicationContext context;
#RequestMapping(value = "/weather")
public void printWeather() {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>(headers);
String text = restTemplate.exchange("http://api.openweathermap.org/data/2.5/weather?q=London,uk&APPID=mykey",
HttpMethod.GET, entity, String.class).getBody();
int pressureStartIndex = text.indexOf("pressure")+10;
int pressureEndIndex = text.indexOf(",", pressureStartIndex);
int tempStartIndex = text.indexOf("temp")+6;
int tempEndIndex = text.indexOf(",", tempStartIndex);
int pressure = Integer.parseInt(text.substring(pressureStartIndex, pressureEndIndex));
double temperature = Double.parseDouble(text.substring(tempStartIndex, tempEndIndex));
WeatherScore score = new WeatherScore();
score.setCity("London");
score.setPressure(pressure);
score.setTemperature(temperature);
Random generator = new Random();
score.setId(generator.nextInt(1000));
score.setCurrentDate(System.currentTimeMillis());
WeatherCRUDRepository repo = context.getBean(WeatherCRUDRepository.class);
repository.save(score);
}
}
When i tap http://localhost:8080/weather i get an error:
Cannot invoke
"org.springframework.context.ApplicationContext.getBean(java.lang.Class)"
because "this.context" is null
Blockquote
How i could fix that?
You have to autowire all the beans within controller, like so:
#Autowired
RestTemplate restTemplate;
#Autowired
WeatherCRUDRepository repository;
#Autowired
ApplicationContext context;

Hibernate one to many input using json with POSTMAN

The problem is one to many hibernate mapping is not working in this json format. I think it's a logical error, syntax error is not shown.
My Controller is:
#RequestMapping(value = "/save", method = RequestMethod.POST, produces =MediaType.APPLICATION_JSON_VALUE,headers="Accept=application/json,application/xml")
public #ResponseBody JsonRecord setCurrentDataList(#RequestBody Employee emp) {
try {
int id=employeeServices.save(emp);
} catch (Exception e) {
return new JsonRecord(false,e.getMessage());
}
return new JsonRecord(true,"Successful",emp);
}
Employee Entity Class is:
import java.io.Serializable;
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;
import javax.persistence.Transient;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.IndexColumn;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.annotation.JsonProperty;
#Entity
#Table(name="Employee")
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
#JsonAutoDetect(getterVisibility=JsonAutoDetect.Visibility.NONE)
public class Employee implements Serializable{
private static final long serialVersionUID = -723583058586873479L;
#Id
#GeneratedValue
#Column(name ="empId")
#JsonProperty("empId")
private Integer empId;
#JsonProperty("empName")
private String empName;
#JsonProperty("empAddress")
private String empAddress;
#JsonProperty("salary")
private double salary;
#JsonProperty("empAge")
private Integer empAge;
#OneToMany(mappedBy="employee",cascade=CascadeType.ALL,fetch=FetchType.EAGER)
#Fetch(FetchMode.SELECT)
private List<Education> education;
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getEmpAddress() {
return empAddress;
}
public void setEmpAddress(String empAddress) {
this.empAddress = empAddress;
}
public double getSalary() {
return salary;
}
public void setSalary(double d) {
this.salary = d;
}
public Integer getEmpAge() {
return empAge;
}
public void setEmpAge(Integer empAge) {
this.empAge = empAge;
}
#OneToMany(fetch = FetchType.EAGER, mappedBy = "employee")
#JsonManagedReference
public List<Education> getEducation() {
return education;
}
public void setEducation(List<Education> education) {
this.education = education;
}
}
Education Entity is:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonProperty;
#Entity
#Table(name="Education")
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
#JsonAutoDetect(getterVisibility=JsonAutoDetect.Visibility.NONE)
public class Education{
#Id
#GeneratedValue
#Column(name ="eduID")
#JsonProperty("eduID")
private int eduID;
#JsonProperty("qualification")
private String qualification;
#JsonProperty("stream")
private String stream;
#ManyToOne
#JoinColumn(name="empid")
private Employee employee;
public int getEduID() {
return eduID;
}
public void setEduID(int eduID) {
this.eduID = eduID;
}
public String getQualification() {
return qualification;
}
public void setQualification(String qualification) {
this.qualification = qualification;
}
public String getStream() {
return stream;
}
public void setStream(String stream) {
this.stream = stream;
}
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "empId", nullable = false)
#JsonBackReference
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
}
JSON input:
{
"empName": "myname",
"empAddress": "my address",
"salary": 1000,
"empAge": 24,
"education":[{
"qualification":"mca",
"stream":"mca"
}]
}
One to many mapping is not working with this json format.How to implement this mapping in json format? Please give me your valuable suggestions.
use
#OneToMany(cascade={CascadeType.ALL})
#Fetch(FetchMode.JOIN)
#JoinColumn(name="empId", referencedColumnName="empId")
private Set<Education> education;
instead of,
#OneToMany(mappedBy="employee",cascade=CascadeType.ALL,fetch=FetchType.EAGER)
#Fetch(FetchMode.SELECT)
private List<Education> education;