How to increment primary key without check AUTOINCREMENT in MySQL?
My Example:
Tax.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package newpackage;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.persistence.*;
import javax.transaction.UserTransaction;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
/**
*
* #author gile
*/
#Entity
#Table(name = "tax", catalog = "invoicedb", schema = "")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Tax.findAll", query = "SELECT t FROM Tax t"),
#NamedQuery(name = "Tax.findByIdtax", query = "SELECT t FROM Tax t WHERE t.idtax = :idtax"),
#NamedQuery(name = "Tax.findByValue", query = "SELECT t FROM Tax t WHERE t.value = :value"),
**#NamedQuery(name = "Tax.findMaxID", query = "SELECT MAX (t.idtax) from Tax t")})** // I write this query to find max value of primary key. how to find max ?
public class Tax implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Column(name = "idtax")
private Integer idtax;
#Basic(optional = false)
#NotNull
#Column(name = "value")
private BigDecimal value;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "taxid")
private List<Invoicedetails> invoicedetailsList;
public Tax() {
}
public Tax(Integer idtax) {
this.idtax = idtax;
}
public Tax(Integer idtax, BigDecimal value) {
this.idtax = idtax;
this.value = value;
}
public Integer getIdtax() {
return idtax;
}
public void setIdtax(Integer idtax) {
this.idtax = idtax;
}
public BigDecimal getValue() {
return value;
}
public void setValue(BigDecimal value) {
this.value = value;
}
#XmlTransient
public List<Invoicedetails> getInvoicedetailsList() {
return invoicedetailsList;
}
public void setInvoicedetailsList(List<Invoicedetails> invoicedetailsList) {
this.invoicedetailsList = invoicedetailsList;
}
#Override
public int hashCode() {
int hash = 0;
hash += (idtax != null ? idtax.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Tax)) {
return false;
}
Tax other = (Tax) object;
if ((this.idtax == null && other.idtax != null) || (this.idtax != null && !this.idtax.equals(other.idtax))) {
return false;
}
return true;
}
#Override
public String toString() {
return String.format("%.2f %%",value);
}
#Transient
private String taxvalueString;
public String getTaxvalueString() {
return String.format(" %.2f %%",value);
}
public void setTaxvalueString(String taxvalueString) {
this.taxvalueString = taxvalueString;
}
}
You can add a method in Tax Class with PrePersit annotation for creating PK (idtax)
like
#PrePersist
private void generateID() {
// Read existing Tax record, finde new id and set pk here.
}
Related
I am trying to have the api return a list of notes, associated by a many to many relationship with labels, given a label id. Spring boot automatically created a bridge table called notes_tables with a notes_id field and a labels_id field. Spring Boot also created a notes table and a labels table. I attempted the following:
#Query(value="select * from notes join notes_labels on note.id=notes_id join labels on labels_id=labels.id where labels_id=:lid", nativeQuery=true)
public List<Note> findNotesForLabel(#Param("lid") int labelId);
I just need to get this to work but I am specifically curious if I can get it to work with jpa method query. Any query will do as long as it works though.
EDIT:
Entities
Note.java
package com.example.maapi.models;
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.persistence.*;
import java.util.List;
import java.util.Objects;
#Entity
#Table(name = "notes")
public class Note {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String note;
private String title;
private String status = "private";
#ManyToOne
#JsonIgnore
private User user;
#ManyToOne
#JsonIgnore
private Folder folder;
#ManyToMany
#JsonIgnore
private List<Label> labels;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Folder getFolder() {
return folder;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public void setFolder(Folder folder) {
this.folder = folder;
}
public List<Label> getLabels() {
return labels;
}
public void setLabels(List<Label> labels) {
this.labels = labels;
}
#Override
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Note)) {
return false;
}
Note note = (Note) o;
return id == note.id && Objects.equals(note, note.note) &&
Objects.equals(title, note.title) && Objects.equals(status,
note.status) && Objects.equals(user, note.user) &&
Objects.equals(folder, note.folder) && Objects.equals(labels,
note.labels);
}
#Override
public int hashCode() {
return Objects.hash(id, note, title, status, user, folder,
labels);
}
}
Label.java
package com.example.maapi.models;
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.persistence.*;
import java.util.List;
import java.util.Objects;
#Entity
#Table(name = "labels")
public class Label {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String title;
private String status = "private";
#ManyToOne
#JsonIgnore
private User user;
#ManyToOne
#JsonIgnore
private Folder folder;
#ManyToMany(mappedBy = "labels")
#JsonIgnore
private List<Note> notes;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Folder getFolder() {
return folder;
}
public void setFolder(Folder folder) {
this.folder = folder;
}
public List<Note> getNotes() {
return notes;
}
public void setNotes(List<Note> notes) {
this.notes = notes;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
#Override
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Label)) {
return false;
}
Label label = (Label) o;
return id == label.id && Objects.equals(title, label.title) &&
Objects.equals(status, label.status) && Objects.equals(user,
label.user) && Objects.equals(folder, label.folder) &&
Objects.equals(notes, label.notes);
}
#Override
public int hashCode() {
return Objects.hash(id, title, status, user, folder, notes);
}
}
Services:
NoteService.java
package com.example.maapi.services;
import com.example.maapi.models.Folder;
import com.example.maapi.models.Note;
import com.example.maapi.models.User;
import com.example.maapi.repositories.FolderRepo;
import com.example.maapi.repositories.NoteRepo;
import com.example.maapi.repositories.UserRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
#Service
public class NoteService {
#Autowired
NoteRepo noteRepo;
#Autowired
UserRepo userRepo;
#Autowired
FolderRepo folderRepo;
public List<Note> findAllNotes(){
return noteRepo.findAllNotes();
}
public Note findNoteById(int noteId){
return noteRepo.findNoteById(noteId);
}
public List<Note> findNotesByUser(int userId){
return noteRepo.findNotesByUser(userId);
}
public Note createNoteForUser(int userId, Note note){
User user = userRepo.findUserById(userId);
note.setUser(user);
return noteRepo.save(note);
}
public List<Note> findNotesByFolder(int folderId){
return noteRepo.findNotesByFolder(folderId);
}
public Note createNoteForFolder(int folderId, Note note){
Folder folder = folderRepo.findFolderById(folderId);
note.setFolder(folder);
note.setUser(folder.getUser());
return noteRepo.save(note);
}
public int updateNote(int noteId, Note updatedNote){
Note note = noteRepo.findNoteById(noteId);
updatedNote.setUser(note.getUser());
updatedNote.setFolder(note.getFolder());
noteRepo.save(updatedNote);
if(updatedNote.equals(note)){
return 1;
} else {
return 0;
}
}
public int deleteNote(int noteId){
noteRepo.deleteById(noteId);
if(noteRepo.findNoteById(noteId) == null) {
return 1;
} else {
return 0;
}
}
// SEARCH IMPLEMENTATION
public List<Note> searchForNote(String note){
return noteRepo.searchForNote(note);
}
}
LabelService.java
So this is the spring-booty way to do this that I was able to figure out. CrudRepository has findById(Integer id) which returns an Optional object.
All you have to do is optional.get() to return the encapsulated object and then you can return the desired field (in my case List notes) with a getter.
// CrudRepo interface provides the findById method which returns an Optional<Label>
// object that may or may not exist. Optional.get() returns the encapsulated object.
public List<Note> findNotesByLabelId(int labelId) {
Optional<Label> label = labelRepo.findById(labelId);
return label.get().getNotes();
}
Try this one!
SELECT * FROM notes n INNER JOIN notes_labels nl ON nl.notes_id = n.note_id WHERE nl.labels_id = ?1
Edit:
#Entity
#Table(name = "notes")
#NamedNativeQuery(name = "Note.getNoteByLabel", resultSetMapping = "getNote",
query = "SELECT n.id,n.note,n.title,n.status FROM notes n INNER JOIN notes_labels nl ON nl.notes_id = n.note_id WHERE nl.labels_id = ?1")
#SqlResultSetMapping(name = "getNote", classes = #ConstructorResult(targetClass = Note.class,
columns = {#ColumnResult(name = "id", type = Integer.class),#ColumnResult(name = "note", type = String.class)
#ColumnResult(name = "title", type = String.class),#ColumnResult(name = "status", type = String.class)}))
public class Note {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String note;
private String title;
private String status = "private";
NoteRepo.java
#Query(nativeQuery = true)
List<Note> getNoteByLabel(int labelId);
Build a proper constructor and try this one.
You have to think on it as if it was simple POO. For example, you can use:
#Query("FROM Note n WHERE (SELECT l FROM Label l WHERE l.id = :lid) MEMBER OF labels")
public List<Note> findNotesByLabel(#Param("lid") int id);
which basically means,
get all notes where given id's label is part of the labels attribute
I don't fully know each implementation yet, surely the documentation would give a better approach, but I just came up with that problem and it did the trick
I have this error when I trying to send a GET request to my Spring Boot Application and I don't know what I missed out!
I have this database and I created the JPA Entities and the relationships in Eclipse, with STS (Spring Tool Suite) installed for my Spring Boot Project, accordingly.
The Entities created are:
Categoria.java
package gnammy.entities;
import java.io.Serializable;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
* The persistent class for the categoria database table.
*
*/
#Entity
#Table(name = "categoria")
#NamedQuery(name = "Categoria.findAll", query = "SELECT c FROM Categoria c")
#NamedQuery(name = "Categoria.findByIdRistorante", query = "SELECT DISTINCT c FROM Categoria c INNER JOIN c.portate p INNER JOIN p.ristoranti r WHERE r.idRistorante = :idRistorante")
public class Categoria implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "idCategoria", nullable = false, unique = true, insertable = false, updatable = false)
private int idCategoria;
private String descrizione;
// bi-directional many-to-one association to Portata
#OneToMany(mappedBy = "categoria")
private List<Portata> portate;
public Categoria() {
}
public Categoria(String descrizione) {
super();
this.descrizione = descrizione;
}
public Categoria(int idCategoria, String descrizione) {
super();
this.idCategoria = idCategoria;
this.descrizione = descrizione;
}
public int getIdCategoria() {
return idCategoria;
}
public void setIdCategoria(int idCategoria) {
this.idCategoria = idCategoria;
}
public String getDescrizione() {
return this.descrizione;
}
public void setDescrizione(String descrizione) {
this.descrizione = descrizione;
}
public List<Portata> getPortate() {
return this.portate;
}
public void setPortate(List<Portata> portatas) {
this.portate = portatas;
}
public Portata addPortata(Portata portata) {
getPortate().add(portata);
portata.setCategoria(this);
return portata;
}
public Portata removePortata(Portata portata) {
getPortate().remove(portata);
portata.setCategoria(null);
return portata;
}
}
Ordine.java
package gnammy.entities;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* The persistent class for the ordine database table.
*
*/
#Entity
#Table(name = "ordine")
#NamedQuery(name = "Ordine.findAll", query = "SELECT o FROM Ordine o")
public class Ordine implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "idOrdine", nullable = false, unique = true, insertable = false, updatable = false)
private int idOrdine;
#Column(name = "idRistorante", nullable = false, unique = true, insertable = false, updatable = false)
private int idRistorante;
private String indirizzoConsegna;
#Temporal(TemporalType.TIMESTAMP)
#JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date orarioConsegna;
private String tipoPagamento;
private String note;
#Temporal(TemporalType.TIMESTAMP)
#JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date dataOrdine;
private float totale;
private String cartaDiCredito;
// bi-directional many-to-many association to Portata
#ManyToMany
#JoinTable(name = "ordine_portata", joinColumns = {
#JoinColumn(name = "IdOrdine", referencedColumnName = "IdOrdine") }, inverseJoinColumns = {
#JoinColumn(name = "IdPortata", referencedColumnName = "IdPortata") })
private List<Portata> portate;
// bi-directional many-to-one association to Ristorante
#ManyToOne
#JoinColumn(name = "IdRistorante", referencedColumnName = "IdRistorante")
private Ristorante ristorante;
public Ordine() {
}
public Ordine(int idRistorante, String indirizzoConsegna, Date orarioConsegna, String tipoPagamento, String note,
Date dataOrdine, float totale, String cartaDiCredito) {
super();
this.idRistorante = idRistorante;
this.indirizzoConsegna = indirizzoConsegna;
this.orarioConsegna = orarioConsegna;
this.tipoPagamento = tipoPagamento;
this.note = note;
this.dataOrdine = dataOrdine;
this.totale = totale;
this.cartaDiCredito = cartaDiCredito;
}
public Ordine(int idOrdine, int idRistorante, String indirizzoConsegna, Date orarioConsegna, String tipoPagamento,
String note, Date dataOrdine, float totale, String cartaDiCredito) {
super();
this.idOrdine = idOrdine;
this.idRistorante = idRistorante;
this.indirizzoConsegna = indirizzoConsegna;
this.orarioConsegna = orarioConsegna;
this.tipoPagamento = tipoPagamento;
this.note = note;
this.dataOrdine = dataOrdine;
this.totale = totale;
this.cartaDiCredito = cartaDiCredito;
}
public int getIdOrdine() {
return idOrdine;
}
public void setIdOrdine(int idOrdine) {
this.idOrdine = idOrdine;
}
public int getIdRistorante() {
return idRistorante;
}
public void setIdRistorante(int idRistorante) {
this.idRistorante = idRistorante;
}
public String getCartaDiCredito() {
return this.cartaDiCredito;
}
public void setCartaDiCredito(String cartaDiCredito) {
this.cartaDiCredito = cartaDiCredito;
}
public Date getDataOrdine() {
return this.dataOrdine;
}
public void setDataOrdine(Date dataOrdine) {
this.dataOrdine = dataOrdine;
}
public String getIndirizzoConsegna() {
return this.indirizzoConsegna;
}
public void setIndirizzoConsegna(String indirizzoConsegna) {
this.indirizzoConsegna = indirizzoConsegna;
}
public String getNote() {
return this.note;
}
public void setNote(String note) {
this.note = note;
}
public Date getOrarioConsegna() {
return this.orarioConsegna;
}
public void setOrarioConsegna(Date orarioConsegna) {
this.orarioConsegna = orarioConsegna;
}
public String getTipoPagamento() {
return this.tipoPagamento;
}
public void setTipoPagamento(String tipoPagamento) {
this.tipoPagamento = tipoPagamento;
}
public float getTotale() {
return this.totale;
}
public void setTotale(float totale) {
this.totale = totale;
}
public List<Portata> getPortate() {
return this.portate;
}
public void setPortate(List<Portata> portate) {
this.portate = portate;
}
public Ristorante getRistorante() {
return this.ristorante;
}
public void setRistorante(Ristorante ristorante) {
this.ristorante = ristorante;
}
}
Portata.java
package gnammy.entities;
import java.io.Serializable;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
/**
* The persistent class for the portata database table.
*
*/
#Entity
#Table(name = "portata")
#NamedQuery(name = "Portata.findAll", query = "SELECT p FROM Portata p")
#NamedQuery(name = "Portata.findByIdRistorante", query = "SELECT DISTINCT p FROM Portata p INNER JOIN p.ristoranti r WHERE r.idRistorante = :idRistorante")
public class Portata implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "idPortata", nullable = false, unique = true, insertable = false, updatable = false)
private int idPortata;
#Column(name = "idCategoria", nullable = false, unique = true, insertable = false, updatable = false)
private int idCategoria;
private String nome;
private String descrizione;
private float prezzo;
// bi-directional many-to-many association to Ordine
#ManyToMany(mappedBy = "portate")
private List<Ordine> ordini;
// bi-directional many-to-one association to Categoria
#ManyToOne
#JoinColumn(name = "IdCategoria", referencedColumnName = "IdCategoria")
private Categoria categoria;
// bi-directional many-to-many association to Ristorante
#ManyToMany(mappedBy = "portate")
private List<Ristorante> ristoranti;
public Portata() {
}
public Portata(int idCategoria, String nome, String descrizione, float prezzo) {
super();
this.idCategoria = idCategoria;
this.nome = nome;
this.descrizione = descrizione;
this.prezzo = prezzo;
}
public Portata(int idPortata, int idCategoria, String nome, String descrizione, float prezzo) {
super();
this.idPortata = idPortata;
this.idCategoria = idCategoria;
this.nome = nome;
this.descrizione = descrizione;
this.prezzo = prezzo;
}
public int getIdPortata() {
return idPortata;
}
public void setIdPortata(int idPortata) {
this.idPortata = idPortata;
}
public int getIdCategoria() {
return idCategoria;
}
public void setIdCategoria(int idCategoria) {
this.idCategoria = idCategoria;
}
public String getDescrizione() {
return this.descrizione;
}
public void setDescrizione(String descrizione) {
this.descrizione = descrizione;
}
public String getNome() {
return this.nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public float getPrezzo() {
return this.prezzo;
}
public void setPrezzo(float prezzo) {
this.prezzo = prezzo;
}
public List<Ordine> getOrdini() {
return this.ordini;
}
public void setOrdini(List<Ordine> ordini) {
this.ordini = ordini;
}
public Categoria getCategoria() {
return this.categoria;
}
public void setCategoria(Categoria categoria) {
this.categoria = categoria;
}
public List<Ristorante> getRistoranti() {
return this.ristoranti;
}
public void setRistoranti(List<Ristorante> ristoranti) {
this.ristoranti = ristoranti;
}
}
Ristorante.java
package gnammy.entities;
import java.io.Serializable;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
* The persistent class for the ristorante database table.
*
*/
#Entity
#Table(name = "ristorante")
#NamedQuery(name = "Ristorante.findAll", query = "SELECT r FROM Ristorante r")
#NamedQuery(name = "Ristorante.findByIdTipoCucina", query = "SELECT DISTINCT r FROM Ristorante r INNER JOIN r.tipiCucina tc WHERE tc.idTipoCucina = :idTipoCucina")
public class Ristorante implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "idRistorante", nullable = false, unique = true, insertable = false, updatable = false)
private int idRistorante;
private String nome;
private String indirizzo;
private String numeroTelefonico;
private String orario;
private float costoDiConsegna;
private float ordineMinimo;
private String linkSito;
// bi-directional many-to-one association to Ordine
#OneToMany(mappedBy = "ristorante")
private List<Ordine> ordini;
// bi-directional many-to-many association to Portata
#ManyToMany
#JoinTable(name = "ristorante_portata", joinColumns = {
#JoinColumn(name = "IdRistorante", referencedColumnName = "IdRistorante") }, inverseJoinColumns = {
#JoinColumn(name = "IdPortata", referencedColumnName = "IdPortata") })
private List<Portata> portate;
// bi-directional many-to-many association to TipoCucina
#ManyToMany
#JoinTable(name = "ristorante_tipo_cucina", joinColumns = {
#JoinColumn(name = "IdRistorante", referencedColumnName = "IdRistorante") }, inverseJoinColumns = {
#JoinColumn(name = "IdTipoCucina", referencedColumnName = "IdTipoCucina") })
private List<TipoCucina> tipiCucina;
public Ristorante() {
}
public Ristorante(String nome, String indirizzo, String numeroTelefonico, String orario, float costoDiConsegna,
float ordineMinimo, String linkSito) {
super();
this.nome = nome;
this.indirizzo = indirizzo;
this.numeroTelefonico = numeroTelefonico;
this.orario = orario;
this.costoDiConsegna = costoDiConsegna;
this.ordineMinimo = ordineMinimo;
this.linkSito = linkSito;
}
public Ristorante(int idRistorante, String nome, String indirizzo, String numeroTelefonico, String orario,
float costoDiConsegna, float ordineMinimo, String linkSito) {
super();
this.idRistorante = idRistorante;
this.nome = nome;
this.indirizzo = indirizzo;
this.numeroTelefonico = numeroTelefonico;
this.orario = orario;
this.costoDiConsegna = costoDiConsegna;
this.ordineMinimo = ordineMinimo;
this.linkSito = linkSito;
}
public int getIdRistorante() {
return idRistorante;
}
public void setIdRistorante(int idRistorante) {
this.idRistorante = idRistorante;
}
public float getCostoDiConsegna() {
return this.costoDiConsegna;
}
public void setCostoDiConsegna(float costoDiConsegna) {
this.costoDiConsegna = costoDiConsegna;
}
public String getIndirizzo() {
return this.indirizzo;
}
public void setIndirizzo(String indirizzo) {
this.indirizzo = indirizzo;
}
public String getLinkSito() {
return this.linkSito;
}
public void setLinkSito(String linkSito) {
this.linkSito = linkSito;
}
public String getNome() {
return this.nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getNumeroTelefonico() {
return this.numeroTelefonico;
}
public void setNumeroTelefonico(String numeroTelefonico) {
this.numeroTelefonico = numeroTelefonico;
}
public String getOrario() {
return this.orario;
}
public void setOrario(String orario) {
this.orario = orario;
}
public float getOrdineMinimo() {
return this.ordineMinimo;
}
public void setOrdineMinimo(float ordineMinimo) {
this.ordineMinimo = ordineMinimo;
}
public List<Ordine> getOrdini() {
return this.ordini;
}
public void setOrdini(List<Ordine> ordini) {
this.ordini = ordini;
}
public Ordine addOrdine(Ordine ordine) {
getOrdini().add(ordine);
ordine.setRistorante(this);
return ordine;
}
public Ordine removeOrdine(Ordine ordine) {
getOrdini().remove(ordine);
ordine.setRistorante(null);
return ordine;
}
public List<Portata> getPortate() {
return this.portate;
}
public void setPortate(List<Portata> portate) {
this.portate = portate;
}
public List<TipoCucina> getTipiCucina() {
return this.tipiCucina;
}
public void setTipiCucina(List<TipoCucina> tipiCucina) {
this.tipiCucina = tipiCucina;
}
}
TipoCucina.java
package gnammy.entities;
import java.io.Serializable;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
/**
* The persistent class for the tipo_cucina database table.
*
*/
#Entity
#Table(name = "tipo_cucina")
#NamedQuery(name = "TipoCucina.findAll", query = "SELECT t FROM TipoCucina t")
public class TipoCucina implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "idTipoCucina", nullable = false, unique = true, insertable = false, updatable = false)
private int idTipoCucina;
private String descrizione;
private String immagine;
// bi-directional many-to-many association to Ristorante
#ManyToMany(mappedBy = "tipiCucina")
private List<Ristorante> ristoranti;
public TipoCucina() {
}
public TipoCucina(String descrizione, String immagine) {
super();
this.descrizione = descrizione;
this.immagine = immagine;
}
public TipoCucina(int idTipoCucina, String descrizione, String immagine) {
super();
this.idTipoCucina = idTipoCucina;
this.descrizione = descrizione;
this.immagine = immagine;
}
public int getIdTipoCucina() {
return idTipoCucina;
}
public void setIdTipoCucina(int idTipoCucina) {
this.idTipoCucina = idTipoCucina;
}
public String getDescrizione() {
return this.descrizione;
}
public void setDescrizione(String descrizione) {
this.descrizione = descrizione;
}
public String getImmagine() {
return this.immagine;
}
public void setImmagine(String immagine) {
this.immagine = immagine;
}
public List<Ristorante> getRistorantes() {
return this.ristoranti;
}
public void setRistorantes(List<Ristorante> ristorantes) {
this.ristoranti = ristorantes;
}
}
What I missed out???
From the stack trace it is evidentthat the spring jpa is converting your column name incorrectly.
java.sql.SQLSyntaxErrorException: Unknown column 'ristorante0_.id_ristorante' in 'field list'
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120) ~[mysql-connector-java-8.0.15.jar:8.0.15]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) ~[mysql-connector-java-8.0.15.jar:8.0.15]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-java-8.0.15.jar:8.0.15]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:970) ~[mysql-connector-java-8.0.15.jar:8.0.15]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:1020) ~[mysql-connector-java-8.0.15.jar:8.0.15]
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52) ~[HikariCP-3.3.1.jar:na]
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java) ~[HikariCP-3.3.1.jar:na]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:60) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.loader.Loader.getResultSet(Loader.java:2173) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1936) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1898) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.loader.Loader.doQuery(Loader.java:937) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:340) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2695) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.loader.Loader.doList(Loader.java:2678) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2512) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.loader.Loader.list(Loader.java:2507) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:504) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:396) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:224) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1538) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1561) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1529) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at org.hibernate.query.Query.getResultList(Query.java:165) ~[hibernate-core-5.4.2.Final.jar:5.4.2.Final]
at gnammy.repositories.RistoranteRepositoryImpl.listaRistoranti(RistoranteRepositoryImpl.java:54) ~[classes/:na]
In your stack trace while trying to execute the method listaRistoranti(RistoranteRepositoryImpl.java:54) on the Entity class Ristorante , jpa converts the column name given as #Column(name = "idRistorante") to the camel case id_ristorante ,while in the database the column name is idRistorante itself, which is causing the issue.
From the Configure Hibernate Naming Strategy section of the Spring data access howto guides:
Hibernate uses two different naming strategies to map names from the object model to the corresponding database names. The fully qualified class name of the physical and the implicit strategy implementations can be configured by setting the spring.jpa.hibernate.naming.physical-strategy and spring.jpa.hibernate.naming.implicit-strategy properties, respectively. Alternatively, if ImplicitNamingStrategy or PhysicalNamingStrategy beans are available in the application context, Hibernate will be automatically configured to use them.
By default, Spring Boot configures the physical naming strategy with
SpringPhysicalNamingStrategy. This implementation provides the same
table structure as Hibernate 4: all dots are replaced by underscores
and camel casing is replaced by underscores as well. By default, all
table names are generated in lower case, but it is possible to
override that flag if your schema requires it.
Try using the following property in the application.properties or application.yml whichever you are using, so that spring jpa does not convert your column name and use it as it is specified in your Entity.
Application.yml
spring:
jpa:
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
I am new to Neo4j and I want to connect a node (Person) with a node (Asset) but also, store the time that this connection has been created. I figured out that I have to use #RelatedtoVia annotation. I have followed the Spring cineasts tutorial ([https://github.com/spring-projects/spring-data-neo4j/tree/master/spring-data-neo4j-examples/cineasts][1] ) Although, everything works fine as far as the tests and the database population are concerned, I get weird results at the REST service. Here is my code:
Node Person
import org.neo4j.helpers.collection.IteratorUtil;
import org.springframework.data.neo4j.annotation.*;
import org.springframework.data.neo4j.template.Neo4jOperations;
import java.util.*;
#NodeEntity
public class Person {
#GraphId
Long id;
#Indexed
private String displayName;
#Indexed(unique = true, failOnDuplicate = true)
private Long personId;
private String firstName;
private String lastName;
private Date birthday;
private String aboutMe;
private String thumbnailURL;
private String email;
private enum gendertypes {male, female, other};
private gendertypes gender;
private String[] languages;
private boolean active;
public static final String CONSUMED = "CONSUMED";
//empty & full constructor
//getters&setters
#RelatedToVia(type = "CONSUMED", elementClass = ConsumedDate.class)
#Fetch
Iterable<ConsumedDate> consumedDates;
public ConsumedDate consumedDate(Neo4jOperations template, Asset asset, Date timestamp) {
final ConsumedDate consumedDate = template.createRelationshipBetween(this, asset, ConsumedDate.class, CONSUMED, false).consumedDate(timestamp);
return template.save(consumedDate);
}
public Collection<ConsumedDate> getConsumedDates() {
return IteratorUtil.asCollection(consumedDates);
}
}
Node Asset
import org.neo4j.helpers.collection.IteratorUtil;
import org.springframework.data.neo4j.annotation.*;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import static org.neo4j.graphdb.Direction.INCOMING;
#NodeEntity
public class Asset {
#GraphId
private Long id;
#Indexed(unique=true, failOnDuplicate = true)
private Long assetId;
private String description;
private String type;
private String[] tags;
public Asset() {}
public Asset(Long assetId, String description, String type, String[] tags) {
this.assetId = assetId;
this.description = description;
this.type = type;
this.tags = tags;
}
public Long getAssetId() {return assetId; }
public void setAssetId(Long assetId) {
this.assetId = assetId;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String[] getTags() {
return tags;
}
public void setTags(String[] tags) {
this.tags = tags;
}
#RelatedTo(type = "CONSUMED", direction = INCOMING)
Set<Person> persons;
#RelatedToVia(type="CONSUMED", elementClass=ConsumedDate.class, direction=INCOMING)
#Fetch
Iterable<ConsumedDate> consumedDates;
public Collection<Person> getPersons() {
return persons;
}
public Collection<ConsumedDate> getConsumedDates() {
Iterable<ConsumedDate> allConsumedDates = consumedDates;
return allConsumedDates == null ? Collections.<ConsumedDate>emptyList() : IteratorUtil.asCollection(allConsumedDates);
}
#Override
public String toString() {
return "An asset with ID " + assetId + " description " + description + " type " + type;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Asset asset = (Asset) o;
if (id == null) return super.equals(o);
return id.equals(asset.id);
}
#Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
Relationship Entity ConsumedDate
import org.springframework.data.neo4j.annotation.EndNode;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.RelationshipEntity;
import org.springframework.data.neo4j.annotation.StartNode;
import java.util.Date;
#RelationshipEntity(type = "CONSUMED")
public class ConsumedDate {
#GraphId
Long id;
#EndNode
Asset asset;
#StartNode
Person person;
Date timestamp;
public ConsumedDate consumedDate(Date timestamp){
this.timestamp=timestamp;
return this;
}
public Asset getAsset() {
return asset;
}
public Person getPerson() {
return person;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ConsumedDate consumedDate = (ConsumedDate) o;
if (id == null) return super.equals(o);
return id.equals(consumedDate.id);
}
#Override
public int hashCode() {
return id != null ? id.hashCode() : super.hashCode();
}
}
Controller
import gr.ntua.sam.context.neo4j.AssetRepository;
import gr.ntua.sam.context.neo4j.LocationRepository;
import gr.ntua.sam.context.neo4j.PersonRepository;
import gr.ntua.sam.context.resources.*;
import com.wordnik.swagger.annotations.ApiOperation;
import org.neo4j.graphdb.NotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.text.ParseException;
import java.util.*;
import java.util.List;
#RestController
#Configuration
#EnableNeo4jRepositories
public class ContextController {
#Autowired
Neo4jTemplate template;
#Autowired
AssetRepository assetRepository;
#Autowired
PersonRepository personRepository;
#ApiOperation(value = "Show the available assets", response = Asset.class)
#RequestMapping(value = "/asset", method = RequestMethod.GET)
public ResponseEntity<List<Asset>> getAssets() throws NotFoundException {
List<Asset> results = assetRepository.all();
return new ResponseEntity<List<Asset>>(results, HttpStatus.OK);
}
#ApiOperation(value = "Create a new asset",response = Asset.class)
#RequestMapping(value = "/asset", method = RequestMethod.POST, consumes = "application/json")
public ResponseEntity<Asset> saveAsset(#RequestBody Asset asset) {
Asset savedAsset = assetRepository.save(asset);
return new ResponseEntity<Asset>(savedAsset, HttpStatus.CREATED);
}
//Persons
#ApiOperation(value = "Get a list of all the available Persons")
#RequestMapping(value = "/person", method = RequestMethod.GET)
public ResponseEntity<List<Person>> getPersons() throws ParseException {
List<Person> results = personRepository.all();
return new ResponseEntity<List<Person>>(results, HttpStatus.OK);
}
#ApiOperation(value = "Creates a new Person node to store information about a user", response = Person.class)
#RequestMapping(value = "/person", method = RequestMethod.POST, consumes = "application/json")
public ResponseEntity<Person> savePerson(#RequestBody Person person) {
Person savedPerson = personRepository.save(person);
return new ResponseEntity<Person>(savedPerson, HttpStatus.CREATED);
}
#ApiOperation(value = "Creates relationship between a Person and an Asset")
#RequestMapping(value = "/person/{personId}/consumes/", method = RequestMethod.POST, consumes = "application/json")
public ResponseEntity<Void> consumes(#PathVariable("personId") Long personId, #RequestBody LinkedAsset linkedAsset) {
Person person = personRepository.findByPersonId(personId);
List<Long> assetIds = linkedAsset.getAssetIDs();
for (Long assetId : assetIds) {
Asset currentAsset = assetRepository.findByAssetId(assetId);
Date date= linkedAsset.getTimestamp();
ConsumedDate consumedDate= person.consumedDate(template,currentAsset,date);
template.save(consumedDate);
}
return new ResponseEntity<Void>(HttpStatus.CREATED);
}
The problem is that when I create a relationship between a Person and an Asset, along with a timestamp (I have created the class LinkedAsset which serves as a JSON input model and has nothing to do with Neo4j) and then try to get through REST the person or the asset, all I get is something definitely not JSON with the person or the asset appearing infinite times. Is there a way to face this problem?
Thank you in advance!
I creating "New JPA Controller Classes from Entity Classes" when I press the "FINISH" button and then I get the following error.
Users.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.mycompany.mavenproject1.exceptions.exceptions.exceptions;
import java.io.Serializable;
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.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
/**
*
* #author OZGUR-PC
*/
#Entity
#Table(name = "users")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "Users.findAll", query = "SELECT u FROM Users u"),
#NamedQuery(name = "Users.findById", query = "SELECT u FROM Users u WHERE u.id = :id"),
#NamedQuery(name = "Users.findByUserName", query = "SELECT u FROM Users u WHERE u.userName = :userName")})
public class Users implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 50)
#Column(name = "user_name")
private String userName;
public Users() {
}
public Users(Integer id) {
this.id = id;
}
public Users(Integer id, String userName) {
this.id = id;
this.userName = userName;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Users)) {
return false;
}
Users other = (Users) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "com.mycompany.mavenproject1.exceptions.exceptions.exceptions.Users[ id=" + id + " ]";
}
}
I need ideas on how I can solve it. Thank you in advance for your help.
Make sure you have declared an identifier for your entity. For example let's say there is an entity called Student with identifier as studentId and property name then the entity should be like this, it should have setter and getter methods for your fields:
#Entity
public class Student {
#Id
#GeneratedValue
private int studentId;
private String name;
public String getName() {
return name;
}
public int getStudentId() {
return studentId;
}
public void setStudentId(int studentId) {
this.studentId = studentId;
}
public void setName(String name) {
this.name = name;
}
}
I am using TomeEE + MySql and i have problem because function createNamedQuery don't returns any results. I thought that problem is with my
entityManager but i checked in debugMode and is injected.
This is my code:
User Entity:
package pl.gsite.db.model;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
#Entity
#Table(name = "user")
#XmlRootElement
#NamedQueries({
#NamedQuery(name = "User.loginAndPassword", query = "SELECT u FROM User u WHERE u.login = :login and u.password = :password"),
#NamedQuery(name = "User.findAll", query = "SELECT u FROM User u"),
#NamedQuery(name = "User.findById", query = "SELECT u FROM User u WHERE u.id = :id"),
#NamedQuery(name = "User.findByLogin", query = "SELECT u FROM User u WHERE u.login = :login"),
#NamedQuery(name = "User.findByPassword", query = "SELECT u FROM User u WHERE u.password = :password")})
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Basic(optional = false)
#NotNull
#Column(name = "id")
private Integer id;
#Size(max = 100)
#Column(name = "login")
private String login;
#Size(max = 100)
#Column(name = "password")
private String password;
public User() {
}
public User(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof User)) {
return false;
}
User other = (User) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "pl.gsite.db.model.User[ id=" + id + " ]";
}
}
My ManagedBean:
package pl.gsite.bean.request;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateful;
import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.spi.Context;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import pl.gsite.bean.session.LoggedUserBean;
import pl.gsite.db.model.User;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContextType;
import javax.persistence.Query;
#Named(value = "loginRequest")
#RequestScoped
public class LoginRequest {
#PersistenceContext(unitName = "gsitePU")
private EntityManager em;
#Inject
private LoggedUserBean loggedUserBean;
private String login;
private String password;
public LoginRequest() {
}
public String authentication() {
try {
List<User> uList = new ArrayList<User>();
TypedQuery qq = em.createNamedQuery("User.findAll", User.class);
uList = qq.getResultList(); // <-- returns empty list
TypedQuery<User> query = em.createNamedQuery("User.loginAndPassword", User.class).setParameter("login", login).setParameter("password", password);
User u = query.getSingleResult(); // <-- throws an NoResultException
this.loggedUserBean.setLoggedUser(u);
}
catch(NoResultException e) {
e.printStackTrace();
}
return "index";
}
/**
* #return the login
*/
public String getLogin() {
return login;
}
/**
* #param login the login to set
*/
public void setLogin(String login) {
this.login = login;
}
/**
* #return the password
*/
public String getPassword() {
return password;
}
/**
* #param password the password to set
*/
public void setPassword(String password) {
this.password = password;
}
}
persistance.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="gsitePU" transaction-type="JTA">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>gsite_mysql</jta-data-source>
<properties>
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(foreignKeys=true)"/>
</properties>
</persistence-unit>
</persistence>
I had the same issue. I changed the jpa persistence from openJPA to eclipseLink. The problem resolved.