I am trying to save a list of items from an html table in mysql, but it gives me an error:
Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long[]'; nested exception is java.lang.NumberFormatException: For input string: "{ID}".
My Code is:
Entity Class is
package com.gadpo.cga.app.models.entity;
import java.io.Serializable;
import java.util.Date;
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.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import org.springframework.format.annotation.DateTimeFormat;
#Entity
#Table(name = "paquetes")
public class Paquete implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotEmpty
private String detalle;
#DateTimeFormat(pattern = "yyyy-MM-dd")
#Temporal(TemporalType.DATE)
#NotNull
#Column(name="fecha")
private Date fecha;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval=true)
#JoinColumn(name="paquete_id")
private List<Actividad> actividades;
#NotNull
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval=true)
#JoinColumn(name="paquete_id")
private List<ItemPaquete> items;
//#OneToMany(mappedBy = "paquete", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
//private List<Usuario> usuarios;
public List<ItemPaquete> getItems() {
return items;
}
public void setItems(List<ItemPaquete> items) {
this.items = items;
}
#ManyToOne(fetch = FetchType.LAZY)
private Usuario usuario;
#ManyToOne(fetch = FetchType.LAZY)
private Planificacion planificacion;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDetalle() {
return detalle;
}
public void setDetalle(String detalle) {
this.detalle = detalle;
}
public List<Actividad> getActividades() {
return actividades;
}
public void setActividades(List<Actividad> actividades) {
this.actividades = actividades;
}
public Planificacion getPlanificacion() {
return planificacion;
}
public void setPlanificacion(Planificacion planificacion) {
this.planificacion = planificacion;
}
public Usuario getUsuario() {
return usuario;
}
public void setUsuario(Usuario usuario) {
this.usuario = usuario;
}
public Date getFecha() {
return fecha;
}
public void setFecha(Date fecha) {
this.fecha = fecha;
}
public void addItemPaquete(ItemPaquete item) {
items.add(item);
}
/**
*
*/
private static final long serialVersionUID = 1L;
}
Controller is:
package com.gadpo.cga.app.controller;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.gadpo.cga.app.models.entity.ItemPaquete;
import com.gadpo.cga.app.models.entity.Paquete;
import com.gadpo.cga.app.models.entity.Planificacion;
import com.gadpo.cga.app.models.entity.Usuario;
import com.gadpo.cga.app.models.service.IUsuarioService;
#Controller
#RequestMapping("/paquete")
#SessionAttributes("paquete")
public class PaqueteController {
#Autowired
private IUsuarioService usuarioService;
private final Logger log = LoggerFactory.getLogger(getClass());
#GetMapping("/form/{planificacionId}")
public String crear(#PathVariable(value="planificacionId") Long planificacionId, Map<String, Object> model, RedirectAttributes flash) {
Planificacion planificacion=usuarioService.findPlanificacionById(planificacionId);
if(planificacion==null) {
flash.addFlashAttribute("error","La planificación no existe en la bd");
return "redirect:/listar";
}
Paquete paquete = new Paquete();
paquete.setPlanificacion(planificacion);
model.put("paquete", paquete);
model.put("titulo", "Registro de paquete");
return "paquete/form";
}
#GetMapping(value="/cargar-usuarios/{term}", produces= {"application/json"})
public #ResponseBody List<Usuario>cargarUsuarios(#PathVariable String term){
return usuarioService.findByApellido(term);
}
#PostMapping("/form")
public String guardar(#Valid Paquete paquete,BindingResult result,Model model,
#RequestParam(name="item_id[]",required = false) Long [] itemId,RedirectAttributes flash, SessionStatus status) {
if (result.hasErrors()) {
model.addAttribute("titulo", "Registrar nuevo paquete");
return "paquete/form";
}
for(int i=0; i<itemId.length;i++) {
//System.out.println("ID del usuario: "+itemId[i]);
Usuario usuario = usuarioService.findUsuarioById(itemId[i]);
ItemPaquete linea = new ItemPaquete();
linea.setUsuario(usuario);
paquete.addItemPaquete(linea);
log.info("ID: "+itemId[i].toString());
}
/* if (result.hasErrors()) {
model.addAttribute("titulo", "Formulario de paquete");
return "paquete/form";
}*/
usuarioService.savePaquete(paquete);
status.setComplete();
flash.addFlashAttribute("success","Paquete creado con éxito!");
return "redirect:listar";
}
}
and my form is
form_paquete
The error is happening in your PaqueteController class in the public String guardar method. Your controller is expecting a java.util.Long array (itemId) but is receiving a String instead.
First, you have to remove the [] in your #RequestParam(name="item_id[]").
Then, make sure that the Post requesting you are sending is like:
{
"item_id": [1,2,3],
...
}
in my form plantilla-items.html the name of td is item_id[]
The code in plantilla-items is:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<table th:fragment="itemsPaquete" class="d-none">
<tbody id="plantillaItemsPaquete">
<tr id="row_{ID}">
<td class="d-none"><input type="hidden" value="{ID}"
name="item_id[]" /></td>
<td>{ID}</td>
<td>{NOMBRE}</td>
<td><a href="#" class="btn btn-danger btn-xs"
onclick="itemsHelper.eliminarLineaFactura({ID});">x</a></td>
</tr>
</tbody>
</table>
</body>
</html>
request
When check the request in the brownser, the first element is a string "{ID}" and no understand
Related
This is probebly a repetition to my yesturday's question here
Can't save data to a database with DTO
I can get a request as DTO. But then I convert it to a model class back I get value of regionid column as null.
My DTO Class
package com.example.dto;
import java.util.HashSet;
import java.util.Set;
import lombok.Data;
#Data
public class TownDTO {
public String name;
public String regionid;
}
My model:
package com.example.model;
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.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
#Data
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "towns")
public class Towns {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column(name = "name")
private String name;
#JsonIgnore
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "regionid", nullable = false)
#OnDelete(action = OnDeleteAction.CASCADE)
private Regions regionid;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Regions getRegionid() {
return regionid;
}
public void setRegionid(Regions regionid) {
this.regionid = regionid;
}
}
Controller:
package com.example.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.example.dto.TownDTO;
import com.example.model.Regions;
import com.example.model.Towns;
import com.example.repository.TownsRepository;
import com.example.repository.RegionsRepository;
import java.util.stream.Collectors;
import org.modelmapper.Conditions;
import org.modelmapper.ModelMapper;
#CrossOrigin(origins = "http://localhost:8081")
#RestController
#RequestMapping("/towns")
public class TownsController {
#Autowired
TownsRepository townsrepository;
#Autowired
RegionsRepository regionsrepository;
#Autowired
private ModelMapper modelMapper;
#GetMapping("/list")
public ResponseEntity<List<Towns>> getAllTowns(#RequestParam(required = false) String name) {
try {
List<Towns> towns = new ArrayList<Towns>();
if (name == null)
townsrepository.findAll().forEach(towns::add);
else
townsrepository.findByNameContaining(name).forEach(towns::add);
if (towns.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<>(towns, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
#GetMapping("/list/{id}")
public ResponseEntity<Towns> getTownById(#PathVariable("id") int id) {
Optional<Towns> townData = townsrepository.findById(id);
if (townData.isPresent()) {
return new ResponseEntity<>(townData.get(), HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
#PostMapping("/add")
public ResponseEntity<TownDTO> createPost(#RequestBody TownDTO townDto) {
// convert DTO to entity
Towns townRequest = modelMapper.map(townDto, Towns.class);
System.out.println("reg");
System.out.println(townRequest.getName());
System.out.println(townRequest.getRegionid());
//Regions rid=regionsrepository.findById(2).get();
// townRequest.setRegionid(townDto.regionid);
Towns town = townsrepository.save(townRequest);
// convert entity to DTO
TownDTO townResponse = modelMapper.map(town, TownDTO.class);
return new ResponseEntity<TownDTO>(townResponse, HttpStatus.CREATED);
}
/*
#PostMapping("/addt")
public ResponseEntity<Towns> createtown2(#RequestBody Towns town) {
try {
Towns _town = townsrepository
.save(town);
// Towns _town = townsrepository .save(new Towns( town.getName(), regionsrepository.findByRegionId(town.getRegionid())));
return new ResponseEntity<>(_town, HttpStatus.CREATED);
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.println("region");
System.out.println(town.getRegionid());
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
*/
#PutMapping("/edit/{id}")
/*
public ResponseEntity<Towns> updateTown(#PathVariable("id") int id, #RequestBody Towns town) {
Optional<Towns> townData = townsrepository.findById(id);
if (townData.isPresent()) {
Towns _town = townData.get();
_town.setName(town.getName());
_town.setRegionid(town.getRegionid());
return new ResponseEntity<>(townsrepository.save(_town), HttpStatus.OK);
} else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
*/
#DeleteMapping("/delete/{id}")
public ResponseEntity<HttpStatus> deleteTown(#PathVariable("id") int id) {
try {
townsrepository.deleteById(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
Try to set id to an entety.
Regions rgid=regionsrepository.findById(2).get();
townRequest.setRegionid(rgid.getId());
use ModelMapper.
If your entity class id field uses #Id annotation with auto-generating JPA key like #GeneratedValue(strategy = GenerationType.IDENTITY) as id, then using only model mapper and saving the entity should give you the expected result.
Otherwise, if set your PKID value manually and then save the entity.
Update: for your updated question,
add the whole Region in your Towns entity:
Regions rgid=regionsrepository.findById(2).get();
townRequest.setRegionid(rgid);
I asked previously basically the same question and solved it somehow, but here is a problem again:
I am sending post data from my Angular 12 app
{
"qty": 2,
"paid": 200,
"ticketid": 2
}
This is for userticket model which looks like this in java:
package com.example.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
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 java.util.Date;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#Entity
#Table(name = "tickettouser")
public class TicketUser {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "userid", nullable = false)
#OnDelete(action = OnDeleteAction.CASCADE)
private Users userid;
#Column(name = "qty")
private int qty;
#Column(name = "paid")
private float paid;
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler","ignoreUnknown = true"})
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "ticketid", nullable = false)
#OnDelete(action = OnDeleteAction.CASCADE)
private Tickets ticketid;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Users getUserid() {
return userid;
}
public void setUserid(Users userid) {
this.userid = userid;
}
public int getQty() {
return qty;
}
public void setQty(int qty) {
this.qty = qty;
}
public float getPaid() {
return paid;
}
public void setPaid(float paid) {
this.paid = paid;
}
public Tickets getTicketid() {
return ticketid;
}
public void setTicketid(Tickets ticketid) {
this.ticketid = ticketid;
}
}
The full error:
2021-11-08 14:07:46.938 WARN 8180 --- [nio-8888-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.example.model.Tickets` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (2); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.example.model.Tickets` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (2)
at [Source: (PushbackInputStream); line: 1, column: 32] (through reference chain: com.example.model.TicketUser["ticketid"])]
And my ticket model
package com.example.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
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 java.util.Date;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#Entity
#Table(name = "tickets")
public class Tickets {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "price")
private Float price;
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "event_id", nullable = false)
#OnDelete(action = OnDeleteAction.CASCADE)
private Events eventid;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
public Events getEventid() {
return eventid;
}
public void setEventid(Events eventid) {
this.eventid = eventid;
}
}
And finally my ticketuser controller
package com.example.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
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.servlet.ModelAndView;
import com.example.model.TicketUser;
import com.example.security.services.UserDetailsImp;
import com.example.model.Cities;
import com.example.model.Events;
import com.example.model.Halls;
import com.example.service.UsersticketService;
import com.example.service.EventsService;
import com.example.service.HallsService;
import com.example.service.UsersService;
import com.example.model.Users;
#Controller
#RequestMapping(value="/userticket")
#SpringBootApplication
#CrossOrigin(origins = "http://localhost:8889")
public class UsersTicketController {
#Autowired
UsersticketService usersticketService;
#Autowired
UsersService usersservice;
#RequestMapping(value="/list", method=RequestMethod.GET)
public ResponseEntity list()
{
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String usr= auth.getName();
Users user=usersservice.getUserByLogin(usr);
int id=user.getId();
List<TicketUser> ticketList=usersticketService.getTicketByUser(id);
// user.getId();
//System.out.println(user);
return new ResponseEntity<>(ticketList, HttpStatus.OK);
}
#RequestMapping(value="/add", method=RequestMethod.POST)
public ResponseEntity add(#RequestBody TicketUser ticket)
{
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String usr= auth.getName();
Users user=usersservice.getUserByLogin(usr);
Users userid=new Users();
userid.setId(user.getId());
ticket.setUserid(userid);
usersticketService.addTicket(ticket);
return new ResponseEntity<>(ticket, HttpStatus.CREATED);
}
#RequestMapping(value="/delete/{id}", method=RequestMethod.GET)
public ResponseEntity delete(#PathVariable("id") int id)
{
usersticketService.deleteTicket(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
}
As you can see I don't use any custom deserialize methods or somethin like that. How this problem can be solved?
I see this error if I try to use add method in my controller
Will add TicketuserRepository:
package com.example.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
//import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties.Pageable;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.model.TicketUser;
import com.example.model.Users;
import com.example.model.Events;
import com.example.model.Halls;
#Repository
public interface TicketsUserRepository extends CrudRepository<TicketUser, Integer> {
Page<Events> findByuserid(Integer userid, Pageable pageable);
Optional<Events> findByuseridAndId(Integer userid, Integer id);
Page<Events> findByticketid(Integer ticketid, Pageable pageable);
Optional<Events> findByticketidAndId(Integer ticketid, Integer id);
List<TicketUser> findByUserid(int id);
}
and the service
package com.example.service;
import java.util.List;
import com.example.model.TicketUser;
import com.example.model.Events;
import com.example.model.Halls;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.example.repository.TicketsUserRepository;
import com.example.repository.EventsRepository;
import com.example.repository.HallsRepository;
#Service
#Transactional
public class UsersticketServiceImplementation implements UsersticketService {
#Autowired
TicketsUserRepository ticketsuserRepository;
#Override
public List<TicketUser> getAllTickets() {
// TODO Auto-generated method stub
return (List<TicketUser>) ticketsuserRepository.findAll();
}
#Override
public TicketUser getTicketById(int id) {
// TODO Auto-generated method stub
return ticketsuserRepository.findById(id).get();
}
#Override
public void addTicket(TicketUser ticketuser) {
// TODO Auto-generated method stub
ticketsuserRepository.save(ticketuser);
}
#Override
public void deleteTicket(int id) {
// TODO Auto-generated method stub
ticketsuserRepository.deleteById(id);
}
#Override
public List<TicketUser> getTicketByUser(int id) {
// TODO Auto-generated method stub
return (List<TicketUser>) ticketsuserRepository.findByUserid(id);
}
}
This is my model userticket in angular:
import {Ticket} from "./ticket.model";
export class Userticket {
id?:any;
qty?:number;
paid?:number;
ticketid?:Ticket;
}
Will add my ticketuser comonent from angular
import { Component, OnInit } from '#angular/core';
import { EventService } from 'src/app/services/event.service';
import { Event } from 'src/app/models/event.model';
import {TicketService} from 'src/app/services/ticket.service';
import {Ticket} from "../../models/ticket.model";
import {Userticket} from "../../models/userticket.model";
import {UserticketService} from "../../services/userticket.service";
import {ActivatedRoute, Router} from "#angular/router";
#Component({
selector: 'app-userticket-buy',
templateUrl: './userticket-buy.component.html',
styleUrls: ['./userticket-buy.component.css']
})
export class UserticketBuyComponent implements OnInit {
currentTicket: Ticket = {
price: 0,
eventid:this.retrieveEvents()
};
eventid = this.currentTicket.eventid;
events?: Event[];
submitted = false;
currentUserTicket: Userticket = {
qty: 1,
paid:0,
};
//final current
//end
message = ''
constructor(
private eventService: EventService,
private ticketService:TicketService,
private userticketService:UserticketService,
private route: ActivatedRoute,
private router: Router) { }
ngOnInit(): void {
this.message = '';
this.getTicket(this.route.snapshot.params.id);
}
getTicket(id: string): void {
this.ticketService.get(id)
.subscribe(
data => {
this.currentTicket = data;
console.log(data);
},
error => {
console.log(error);
});
}
//save order
saveOrder(): void {
const data = {
qty: this.currentUserTicket.qty,
paid: this.currentUserTicket.paid,
ticketid: this.currentTicket.id
};
//console.log(data.eventid);
this.userticketService.create(data)
.subscribe(
response => {
console.log("city")
console.log(response);
this.submitted = true;
},
error => {
console.log(error);
});
}
//end
retrieveEvents(): any {
this.eventService.getAll()
.subscribe(
data => {
this.events = data;
console.log(data);
return data;
},
error => {
console.log(error);
return error;
});
}
calculatePrice($event:any){
let n1:number|undefined;
n1=this.currentTicket.price;
let n2:number|undefined;
n2=this.currentUserTicket.qty || 1;
let res:number|undefined;
res=n1 || 1 * n2 || 1;
console.log(this.currentUserTicket.qty);
// #ts-ignore: Object is possibly 'null'.
this.currentUserTicket.paid= this.currentUserTicket.qty*this.currentTicket.price
}
}
And the template:
<div>
<div *ngIf="currentTicket.id" class="edit-form">
<h4>Билет</h4>
<form>
<div class="form-group">
<label for="title">Количество</label>
<input type="number"
class="form-control"
id="title"
[(ngModel)]="currentUserTicket.qty"
name="qty"
(keyup)="calculatePrice($event)"
/>
<input
type="hidden"
class="form-control"
id="id"
[(ngModel)]="currentTicket"
name="ticketid"
/>
</div>
<div class="form-group">
<label for="title">Итого</label>
<input
type="number"
class="form-control"
id="paid"
[(ngModel)]="currentUserTicket.paid"
name="paid"
/>
</div>
<div class="form-group">
<p>Событие: {{currentTicket.eventid?.name}}</p>
<p>Зал: {{currentTicket.eventid?.hallid?.name}}</p>
<p>Город: {{currentTicket.eventid?.cityid?.name}}</p>
</div>
</form>
<button
type="submit"
class="badge badge-success mb-2"
(click)="saveOrder()"
>
Подтвердить
</button>
<p>{{ message }}</p>
</div>
<div *ngIf="!currentTicket.id">
<br />
<p>Нет доступа...</p>
</div>
</div>
Will add my working example from ticket model:
tickets.java
package com.example.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
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 java.util.Date;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#Entity
#Table(name = "tickets")
public class Tickets {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "price")
private Float price;
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "event_id", nullable = false)
#OnDelete(action = OnDeleteAction.CASCADE)
private Events eventid;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
public Events getEventid() {
return eventid;
}
public void setEventid(Events eventid) {
this.eventid = eventid;
}
}
TicketsRepository:
package com.example.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
//import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties.Pageable;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.model.Tickets;
import com.example.model.Events;
import com.example.model.Halls;
#Repository
public interface TicketsRepository extends CrudRepository<Tickets, Integer>{
Page<Events> findByeventid(Integer eventid, Pageable pageable);
Optional<Events> findByeventidAndId(Integer eventid, Integer id);
}
TicketService:
package com.example.service;
import java.util.List;
import com.example.model.Tickets;
import com.example.model.Events;
import com.example.model.Halls;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.repository.EventsRepository;
import com.example.repository.HallsRepository;
import com.example.repository.TicketsRepository;
#Service
#Transactional
public class TicketsServiceImplementation implements TicketsService {
#Autowired
TicketsRepository ticketsRepository;
#Override
public List<Tickets> getAllTickets() {
// TODO Auto-generated method stub
return (List<Tickets>) ticketsRepository.findAll();
}
#Override
public Tickets getTicketById(int id) {
// TODO Auto-generated method stub
return ticketsRepository.findById(id).get();
}
#Override
public void addTicket(Tickets ticket) {
// TODO Auto-generated method stub
ticketsRepository.save(ticket);
}
#Override
public void deleteTicket(int id) {
// TODO Auto-generated method stub
ticketsRepository.deleteById(id);
}
}
And the controller:
package com.example.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
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.servlet.ModelAndView;
import com.example.model.Tickets;
import com.example.model.Events;
import com.example.model.Halls;
import com.example.service.TicketsService;
import com.example.service.EventsService;
import com.example.service.HallsService;
#Controller
#CrossOrigin(origins = "http://localhost:8889")
#RequestMapping(value="/ticket")
#SpringBootApplication
public class TicketsController {
#Autowired
TicketsService ticketsService;
#RequestMapping(value="/list", method=RequestMethod.GET)
public ResponseEntity list()
{
List<Tickets> ticketList=ticketsService.getAllTickets();
return new ResponseEntity<>(ticketList, HttpStatus.OK);
}
#RequestMapping(value="/add", method=RequestMethod.POST)
public ResponseEntity add(#RequestBody Tickets ticket)
{
ticketsService.addTicket(ticket);
return new ResponseEntity<>(ticket, HttpStatus.CREATED);
}
#RequestMapping(value="/delete/{id}", method=RequestMethod.GET)
public ResponseEntity delete(#PathVariable("id") int id)
{
ticketsService.deleteTicket(id);
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
#RequestMapping(value="/getone/{id}", method=RequestMethod.GET)
public ResponseEntity getOne(#PathVariable("id") int id)
{
Tickets ticket= ticketsService.getTicketById(id);
return new ResponseEntity<>(ticket, HttpStatus.OK);
}
}
Basically this is the ticket table controller. It was basically made a same way as UserTicket. Why then I am getting this problem?
The error is that in the model you are using a full object of ticket and that is also marked as nullable = false so while saving the model in database you need to create an object of ticket using theticketId attribute in the request json or change the model’s attribute from type Tickets to int
You are already doing the same thing for user by setting user object.
I have started learning Spring Boot recently.
I am trying to Soft delete the user. I want to soft delete all the Notes of the user when I soft delete the User. But my code is only soft deleting the user, not its notes.
When I am doing soft delete only on notes table, it's working fine but on User Entity, it is only deleting the user.
Notes
package com.we.springmvcboot.Model;
import java.sql.Date;
import java.util.ArrayList;
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.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import com.fasterxml.jackson.annotation.JsonIgnore;
#Entity
#Table(name="Notes")
#Where(clause = "deleted = 'false'")//FALSE
public class Notes {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="NotesID")
private long NotesID;
#Column(name="Title")
private String Title;
#Column(name="Message")
private String Message;
#Column(name="Date")
private String date;
#Column(name="deleted")
private String deleted="false";
#Column(name="label")
private int label=1;
#ManyToOne()
#JoinColumn(name = "UserID", nullable = false)
private User user;
public Notes() {}
public String getDeleted() {
return deleted;
}
public void setDeleted(String deleted) {
this.deleted = deleted;
}
public Notes(String title, String message, String date, User user, int label) {
super();
Title = title;
Message = message;
this.date = date;
this.user = user;
this.label=label;
}
public Notes(long notesID, String title, String message, String date, int label) {
super();
NotesID = notesID;
Title = title;
Message = message;
this.date = date;
this.label=label;
}
public int getLabel() {
return label;
}
public void setLabel(int label) {
this.label = label;
}
public long getNotesID() {
return NotesID;
}
public void setNotesID(long notesID) {
NotesID = notesID;
}
public String getTitle() {
return Title;
}
public void setTitle(String title) {
Title = title;
}
public String getMessage() {
return Message;
}
public void setMessage(String message) {
Message = message;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public void setUser(User user) {
this.user = user;
}
}
User
package com.we.springmvcboot.Model;
import java.util.ArrayList;
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.Table;
import org.hibernate.annotations.Where;
import antlr.collections.List;
#Entity
#Table(name="User")
#Where(clause = "deleted = 'false'")//FALSE
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long UserID;
#Column(name="emailid")
private String emailID;
#Column(name="deleted")
private String deleted="false";
#OneToMany(mappedBy="user", fetch = FetchType.EAGER,cascade=CascadeType.ALL, orphanRemoval=true)
private Set<Notes> usernotes;
public User() {}
public User(String emailID) {
super();
this.emailID = emailID;
}
public long getUserID() {
return UserID;
}
public void setUserID(long userID) {
UserID = userID;
}
public String getemailID() {
return emailID;
}
public void setemailID(String emailID) {
emailID = emailID;
}
public Set<Notes> getUsernotes() {
return usernotes;
}
public void setUsernotes(Set<Notes> usernotes) {
this.usernotes = usernotes;
}
}
NotesRepository
package com.we.springmvcboot.Repository;
import java.sql.Date;
import java.util.List;
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.stereotype.Repository;
import com.we.springmvcboot.Model.Notes;
#Repository
public interface NotesRepository extends JpaRepository<Notes, Long> {
#Query("update Notes e set e.deleted='true' where e.NotesID=?1")
#Transactional
#Modifying
public void softDelete(long id);
}
UserRepository
package com.we.springmvcboot.Repository;
import java.sql.Date;
import java.util.List;
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.stereotype.Repository;
import com.we.springmvcboot.Model.Notes;
import com.we.springmvcboot.Model.User;
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByEmailID(String email);
#Query("update User e set e.deleted='true', where e.UserID=?1")
#Transactional
#Modifying
public void softDelete(long id);
}
TodoService
package com.we.springmvcboot.Service;
import com.we.springmvcboot.Model.*;
import com.we.springmvcboot.exception.*;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import com.we.springmvcboot.Repository.NotesRepository;
import com.we.springmvcboot.Repository.UserRepository;
#Service
public class TodoService {
#Autowired
UserRepository userrepo;
#Autowired
NotesRepository notesrepo;
public Object deleteUser(Map<String, Object> input) {
long userID;
userID = ((Number) input.get("userID")).longValue();
userrepo.softDelete(userID);
return null;
}
}
I would suggest that you read this post for the simplest approach to soft delete. You should arrive at sth like the following:
#SQLDelete("UPDATE User SET deleted = TRUE WHERE id = ?")
#Where(clause = "deleted = FALSE")
public class User {
#OneToMany(mappedBy = "user", fetch = EAGER, cascade=ALL, orphanRemoval = true)
private Set<Notes> usernotes;
...
}
#SQLDelete("UPDATE Note SET deleted = TRUE WHERE id = ?")
#Where(clause = "deleted = FALSE")
public class Note {...}
The above will work if you use the following code to delete a User:
public Object deleteUser(Map<String, Object> input) {
long userID;
userID = ((Number) input.get("userID")).longValue();
User user = userrepo.deleteById(userID);
return null;
}
If you want to keep using the custom query, though, you still need to call a separate query to delete Notes by userId, because Cascade.REMOVE will not be triggered in this case. In other words, you'll want a method like:
public interface NotesRepository extends JpaRepository<Notes, Long> {
#Query("UPDATE Notes n SET n.deleted = TRUE WHERE n.user.id = :id")
public void deleteByUserId(long id);
}
which you then call from deleteUser:
long userID;
userID = ((Number) input.get("userID")).longValue();
userrepo.softDelete(userID);
noteRepo.deleteByUserId(userID);
return null;
I went to develop an application to manage students in a university, I am looking for how to find students in relation to a date entered for that I have developed the following code lines:
1- Model student.java
package com.avatar.model;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.JoinColumn;
#Entity
#Table(name = "Students")
public class Student{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String nom;
private String prenom;
private String numTel;
private String mail;
#Temporal(TemporalType.DATE)
private Date dateCurrent;
#ManyToMany(fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
#JoinTable(name = "student_techno",
joinColumns = { #JoinColumn(name = "student_id") },
inverseJoinColumns = { #JoinColumn(name = "techno_id") })
private Set<Techno> techno = new HashSet<>();
public Student() {
}
#SuppressWarnings("unchecked")
public Student(String nom, String prenom,String numTel, String mail, Date dateCurrent,
) {
super();
this.nom = nom;
this.prenom = prenom;
this.numTel = numTel;
this.mail = mail;
this.dateCurrent = dateCurrent;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getPrenom() {
return prenom;
}
public void setPrenom(String prenom) {
this.prenom = prenom;
}
public String getNumTel() {
return numTel;
}
public void setNumTel(String numTel) {
this.numTel = numTel;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Date getdateCurrent() {
return dateCurrent;
}
public void setdateCurrent(Date dateCurrent) {
this.dateCurrent = dateCurrent;
}
#Override
public String toString() {
return "Student[nom=" + nom + ", prenom=" + prenom + ", numTel=" + numTel + ", mail="
+ mail + ", dateCurrent=" + dateCurrent+ "]";
}
}
2- Controller
package com.avatar.web;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
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 org.springframework.web.bind.annotation.RestController;
import com.avatar.dao.StudentDao;
import com.avatar.model.Student;
#CrossOrigin(origins = "http://localhost:4200")
#RestController
#RequestMapping("/avatar")
public class StudentController {
#Autowired
StudentDao studentdao;
#GetMapping(value = "/all-students")
public List<Student> listeDesStudent() {
List<Student> students= studentdao.findAll();
if (students.isEmpty())
throw new ProductNotFoundException("No student is registered in the database");
return students;
}
#GetMapping(value = "/all-students/dateCurrent/{dateCurrent}")
public List<Student> viewStudent(#PathVariable("dateCurrent") #DateTimeFormat(pattern = "yyyy-MM-dd") Date dateCurrent) {
Calendar c = Calendar.getInstance();
c.setTime(dateCurrent);
c.add(Calendar.DATE, 1);
dateCurrent = c.getTime();
return studentdao.findByDate(dateCurrent);
}
#GetMapping(value = "/all-students /techno/{nomTechno}")
List<Student > viewStudent(#PathVariable("nomTechno") String nomTechno) {
return studentdao.findDistinctByTechnoNomTechno(nomTechno);
}
#PostMapping(value = "/add-student")
public Student addStudent(#RequestBody Student student) {
Student studentAdded= studentdao.save(Student);
return studentAdded;
}
}
3- DAO
package com.avatar.dao;
import java.util.Date;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.avatar.model.Student;
#Repository
public interface StudentDao extends JpaRepository<Student, String> {
List<Student> findByDate(Date dateCurrent);
List<> findDistinctByTechnoNomTechno(String nomTechno);
}
4- applications.properties
server.port= 8080
# MySQL Properties
spring.jpa.show-sql = true
spring.datasource.url= jdbc:mysql://localhost:3306/avatar?serverTimezone=UTC&useLegacyDatetimeCode=false
spring.datasource.username=*****
spring.datasource.password=*****
# Hibernate Properties
spring.jpa.hibernate.ddl-auto=update
in my console i have:
Failed to create query for method public abstract java.util.List com.avatar.dao.StudentDao.findByDate(java.util.Date)! No property date found for type Student!
Please update DAO as per for below mentioned changes
If the field name is dateCurrent then findByDateCurrent.
package com.avatar.dao;
import java.util.Date;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.avatar.model.Student;
#Repository
public interface StudentDao extends JpaRepository<Student, String> {
List<Student> findByDateCurrent(Date dateCurrent);
List<> findDistinctByTechnoNomTechno(String nomTechno);
}
You are missing field name, in Entity class it is not the date by dateCurrent, thus your JPA should be findByDateCurrent
Category EJB
package session;
import com.Entity.Category;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
Item EJB
package session;
import com.Entity.Item;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
#Stateless
public class saveItemBean implements saveItemRemote {
#PersistenceContext
private EntityManager em;
public void saveItem(Item itm) {
em.persist(itm);
}
public void persist(Object object) {
em.persist(object);
}
}
Servlet for save Item
package src;
import com.Entity.Item;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import session.CategoryFacadeRemote;
import session.saveItemRemote;
public class saveItemAndIemCategory extends HttpServlet {
#EJB
private saveItemRemote saveItemBean;
#EJB
private CategoryFacadeRemote categoryFacadeBean;
processRequest(HttpServletRequest request, HttpServletResponse response) {
try {
Item itm = new Item();
itm.setName("HelloNew");
saveItemBean.saveItem(itm);
} catch (Exception e) {
e.printStackTrace();
} finally {
out.close();
}
}
}
Item Entity Bean
package com.Entity;
import java.io.Serializable;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
#Entity
#Table(name = "item")
#NamedQueries({#NamedQuery(name = "Item.findAll", query = "SELECT i FROM Item i"), #NamedQuery(name = "Item.findByItemId", query = "SELECT i FROM Item i WHERE i.itemId = :itemId"), #NamedQuery(name = "Item.findByName", query = "SELECT i FROM Item i WHERE i.name = :name")})
public class Item implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "item_id")
private Integer itemId;
#Basic(optional = false)
#Column(name = "name")
private String name;
#ManyToMany
#JoinTable(name = "item_cat",
joinColumns = {#JoinColumn(name = "item_id", referencedColumnName = "item_id")},
inverseJoinColumns = {#JoinColumn(name = "cat_id", referencedColumnName = "cat_id")})
private List<Category> categoryCollection;
public Item() {
}
public Item(Integer itemId) {
this.itemId = itemId;
}
public Item(Integer itemId, String name) {
this.itemId = itemId;
this.name = name;
}
public Integer getItemId() {
return itemId;
}
public void setItemId(Integer itemId) {
this.itemId = itemId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Category> getCategoryCollection() {
return categoryCollection;
}
public void setCategoryCollection(List<Category> categoryCollection) {
this.categoryCollection = categoryCollection;
}
}
I am trying to persist data using these coding but only Category and Item tables are getting field (Category coding are missing here those are fine) my assosiative table item_cat is not getting saving data.
If you have an intermediate join table, you need to use the #JoinTable annotation:
#JoinTable(name="item_cat", joinColumns={ #JoinColumn(name="item_id") }, inverseJoinColumns={ #JoinColumn(name="category_id") })
Make sure you are setting the entities in both sides before persisting them. Something like this:
Item itm = new Item();
itm.setName("NewItem");
Category cat = new Category();
cat.setName("NewCategory");
itm.getCategoryCollection().add(cat);
cat.getItemCollection().add(itm);
It would be very helpful if you post you Category model.