I have webservice which saves an order in a mysql datbase with Hibernate:
this is my json Input:
{
"consignments": [
{
"entries": [
{
"entryNumber": 0,
"productId": "0563 5231",
"quantity": 1,
"totalPrice": 125.00,
"unit": "pieces"
},
{
"entryNumber": 1,
"productId": "0563 4800",
"quantity": 1,
"totalPrice": 125.00,
"unit": "pieces"
}
],
"price": 125.00
}
],
"currency": "EUR",
"erpCustomerId": "0001709147",
"erpUnitId": "string",
"hybrisOrderId": "1512986259483",
"orderDate": "2017-12-08T15:52:25.560Z",
"paymentType": "string",
"price": {
"deliveryCosts": 1,
"totalCosts": 125.00
},
"shopId": "DE-Site",
"shopID": "DE-Site"
}
This is the order object in java:
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "hybris_order_id")
private String hybrisOrderId;
#Column(name = "erp_unit_id")
private String erpUnitId;
#Column(name = "erp_customer_id")
private String erpCustomerId;
#Column(name = "shop_id")
private String shopId;
#Column(name = "payment_type")
private String paymentType;
#Column(name = "currency")
private String currency;
#Column(name = "order_date")
private ZonedDateTime orderDate;
#OneToOne(cascade = {CascadeType.ALL})
#JoinColumn(unique = true)
private Price price;
#OneToMany(mappedBy = "placedOrder", cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Consignment> consignments = new HashSet<>();
#Column(name = "erp_order_id")
private String erpOrderId;
#Column(name = "erp_accepted_date")
private ZonedDateTime erpAcceptedDate;
This is the consignment java object:
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "hybris_consignment_id")
private String hybrisConsignmentId;
#Column(name = "price")
private Double price;
#JsonIgnore
#ManyToOne(cascade = CascadeType.ALL)
#JoinColumn(name="id",referencedColumnName="id", insertable=false, updatable=false)
private PlacedOrder placedOrder;
#OneToMany(mappedBy = "consignment", cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Entry> entries = new HashSet<>();
This is the entry java object:
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "entry_number")
private Integer entryNumber;
#Column(name = "quantity")
private Integer quantity;
#Column(name = "product_id")
private String productId;
#Column(name = "unit")
private String unit;
#Column(name = "total_price")
private Double totalPrice;
#JsonIgnore
#ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name="id",referencedColumnName="id", insertable=false, updatable=false)
private Consignment consignment;
My Problem is that when I try to get this order I added from the API, it works fine. But it misses one of the entries in the consignment list. When I try to access the entry table, i get this Exception:
Resolved exception caused by Handler execution: org.springframework.orm.jpa.JpaObjectRetrievalFailureException:
Unable to find com.testo.es.cloud.os.domain.Consignment with id 2;
Does anyone have an idea, why the second entry is referenced to a consignment, which doesn't exist?
Best regards
Related
I have following relationship in my spring boot:
public class Clazz {
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Id
#Column(name = "id")
private Integer id;
#Column(name = "lesson_id")
#NotNull(message = "{lesson.is_required}")
private Integer lessonId;
#Column(name = "level_id")
#NotNull(message = "{level.is_required}")
private Integer levelId;
#Column(name = "name")
#NotEmpty(message = "{name.is_required}")
private String name;
#OneToOne
#JoinColumn(name = "lesson_id", referencedColumnName = "id", insertable = false, updatable = false)
private Lesson lesson;
#OneToOne
#JoinColumn(name = "level_id", referencedColumnName = "id", insertable = false, updatable = false)
private Level level;
}
Now my Lesson entity has Level entity:
public class Lesson {
#Id
#Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "name")
#NotEmpty(message = "{name.is_required}")
private String name;
#Column(name = "description")
private String description = "";
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "lesson_id")
Collection<Level> levels = new ArrayList<>();
}
And finally my Level class:
public class Level {
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Id
#Column(name = "id", insertable = false, updatable = false)
private Integer id;
#Column(name = "lesson_id")
private Integer lessonId;
#Column(name = "name")
private String name;
#Column(name = "step")
private Integer step;
#Column(name = "description")
private String description="";
}
With this relationship defined, when I fetch data, getting some extra info in my results:
[
{
"id": 2,
"lessonId": 1,
"levelId": 1,
"name": "English Class March",
"branch": {
"id": 1,
"name": "3 mikr branch",
"email": "",
"phone": "",
"address": "3 mikr, foo, bar"
},
"lesson": {
"id": 1,
"name": "math",
"description": "math lesson",
"levels": [
{
"id": 1,
"lessonId": 1,
"name": "First level",
"step": 1,
"description": "1st level descr"
}
]
},
"level": {
"id": 1,
"lessonId": 1,
"name": "First level",
"step": 1,
"description": "1st level descr"
}
}
]
How can I tell JPA not to fetch sub-entities, ideally I do not need levels in lesson field of result.
Use #JsonIgnore. It can be used at setter,getter or field.
Please refer the code below.
public class Lesson {
#Id #Column(name = "id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "name")
#NotEmpty(message = "{name.is_required}")
private String name;
#Column(name = "description")
private String description = "";
#JsonIgnore // Add this to ignore the property in json output
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "lesson_id")
Collection<Level> levels = new ArrayList<>();
}
enter image description here
I am trying to map some entities to tables in MySQL database using Spring Boot JPA. I have a problem with one of the tables because in that one too many foreign keys are added. I highlighted the columns in the picture. I suppose that the problem might be linked with the fact that the Tutorial table has either One to Many or Many to Many relations with the other 3 tables, but I am not sure
#Entity(name = "authors")
public class Author {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "author_id")
private Long authorId;
#Column(name = "first_name", nullable = false, length = 100)
private String firstName;
#Column(name = "last_name", nullable = false, length = 100)
private String lastName;
#Column(name = "email", length = 320, unique = true)
private String email;
#Column(name = "job_title", length = 255)
private String jobTitle;
#Lob
#Type(type = "org.hibernate.type.BinaryType")
#Column(name = "profile_picture")
private byte[] profilePicture;
#Column(name = "about", length = 2000)
private String about;
#OneToMany(fetch = FetchType.LAZY)
#JoinColumn(name = "author_id")
private List<Tutorial> tutorials;
}
#Entity(name = "categories")
public class Category {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "category_id")
private Long categoryId;
#Column(name = "category_name", nullable = false, unique = true, length = 100)
private String categoryName;
#OneToMany(fetch = FetchType.LAZY)
#JoinColumn(name = "category_id")
private List<Tutorial> tutorials;
}
#Entity(name = "tutorials")
public class Tutorial {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "tutorial_id")
private Long tutorialId;
#Column(name = "tutorial_title", nullable = false, length = 150)
private String tutorialTitle;
#Column(name = "tutorial_description", nullable = false, length = 2000)
private String tutorialDescription;
#Column(name = "time_to_complete")
private Integer timeToComplete;
#Column(name = "date_published")
private Long datePublished;
#Column(name = "last_updated")
private Long lastUpdated;
#ManyToMany(fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
},
mappedBy = "tutorials")
private List<User> users = new ArrayList<>();
#ManyToOne(fetch = FetchType.EAGER)
private Category category;
#ManyToOne(fetch = FetchType.EAGER)
private Author author;
}
Tutorials is the table where the problems appear as 4 foreign keys are generate instead of two
#Entity(name = "users")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "user_id")
private Long userId;
#Column(name = "first_name", nullable = false, length = 100)
private String firstName;
#Column(name = "last_name", nullable = false, length = 100)
private String lastName;
#Column(name = "user_name", nullable = false, unique = true, length = 100)
private String userName;
#Column(name = "age")
private Integer age;
#Column(name = "email", length = 320, unique = true)
private String email;
#ManyToMany(fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
#JoinTable(name = "users_tutorials",
joinColumns = { #JoinColumn(name = "user_id") },
inverseJoinColumns = { #JoinColumn(name = "tutorial_id") })
private List<Tutorial> tutorials = new ArrayList<>();
}
Try this changes:
remove #JoinColumn(name = "author_id")from Author and place in Tutorial:
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "author_id")
private Author author;
remove #JoinColumn(name = "category_id")from Category and place it in Tutorial as well:
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "category_id")
private Author author;
To get more information look here: Baeldung - Hibernate One to Many
I have Many-To-Many relation in my project, i can write in my two Entities table, the relational table does not get anything written.
EspecificacionEscenario Class:
public class EspecificacionEscenario implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idespecificacionEscenario")
private Integer idespecificacionEscenario;
#Column(name = "codigo")
private String codigo;
#Column(name = "fecha")
#Temporal(TemporalType.TIMESTAMP)
private Date fecha;
#Column(name = "nombreProceso")
private String nombreProceso;
#Column(name = "nombreEscenario")
private String nombreEscenario;
#Column(name = "objetivoEscenario")
private String objetivoEscenario;
#Column(name = "lugarEscenario")
private String lugarEscenario;
#Column(name = "recursoEscenario")
private String recursoEscenario;
#Column(name = "restriccionEscenario")
private String restriccionEscenario;
#Column(name = "actoresEscenario")
private String actoresEscenario;
#ManyToMany(mappedBy = "especificacionEscenarioList", fetch = FetchType.LAZY)
private List<Elicitacion> elicitacionList;
#ManyToMany(mappedBy = "especificacionEscenarioList", fetch = FetchType.LAZY)
private List<Episodio> episodioList;
#ManyToMany(mappedBy = "especificacionEscenarioList", fetch = FetchType.LAZY)
private List<Educcion> educcionList;
Episodio class:
public class Episodio implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idepisodio")
private Integer idepisodio;
#Column(name = "codigo")
private String codigo;
#Column(name = "objetivoEpisodio")
private String objetivoEpisodio;
#Column(name = "descripcionEpisodio")
private String descripcionEpisodio;
#Column(name = "recursosEpisodio")
private String recursosEpisodio;
#Column(name = "restriccionEpisodio")
private String restriccionEpisodio;
#Column(name = "actor")
private String actor;
#JoinTable(name = "especificacionEscenarioEpisodio", joinColumns = {
#JoinColumn(name = "idepisodio", referencedColumnName = "idepisodio")}, inverseJoinColumns = {
#JoinColumn(name = "idespecificacionEscenario", referencedColumnName = "idespecificacionEscenario")})
#ManyToMany(fetch = FetchType.LAZY)
private List<EspecificacionEscenario> especificacionEscenarioList;
Main code:
public static void main(String[] args) {
EpisodioDao episodioDao = new EpisodioDao();
EspecificacionEscenarioDao escenarioDao = new EspecificacionEscenarioDao();
Episodio episodio = new Episodio();
episodio.setCodigo("e01");
episodio.setDescripcionEpisodio("descripcion episodio");
EspecificacionEscenario ee = new EspecificacionEscenario();
ee.setCodigo("ee-01");
List<Episodio> listaE = new ArrayList<>();
listaE.add(episodio);
ee.setEpisodioList(listaE);
episodioDao.registrarEpisodio(episodio);
System.exit(0);
}
when doing the persistence in the entities the information is saved automatically, but in the table third table it does not insert the primary keys.
I have added CascadeType.ALL on Episodio as it is the owner of this relation.
Following code may help you. I have tested with spring data jpa.
#Setter
#Getter
#Entity
public class Episodio implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idepisodio")
private Integer idepisodio;
#Column(name = "codigo")
private String codigo;
#Column(name = "objetivoEpisodio")
private String objetivoEpisodio;
#Column(name = "descripcionEpisodio")
private String descripcionEpisodio;
#Column(name = "recursosEpisodio")
private String recursosEpisodio;
#Column(name = "restriccionEpisodio")
private String restriccionEpisodio;
#Column(name = "actor")
private String actor;
#JoinTable(name = "especificacionEscenarioEpisodio",
joinColumns = {
#JoinColumn(name = "idepisodio", referencedColumnName = "idepisodio")},
inverseJoinColumns = {
#JoinColumn(name = "idespecificacionEscenario", referencedColumnName = "idespecificacionEscenario")})
#ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<EspecificacionEscenario> especificacionEscenarioList;
}
#Setter
#Getter
#Entity
public class EspecificacionEscenario implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "idespecificacionEscenario")
private Integer idespecificacionEscenario;
#Column(name = "codigo")
private String codigo;
#Column(name = "fecha")
#Temporal(TemporalType.TIMESTAMP)
private Date fecha;
#Column(name = "nombreProceso")
private String nombreProceso;
#Column(name = "nombreEscenario")
private String nombreEscenario;
#Column(name = "objetivoEscenario")
private String objetivoEscenario;
#Column(name = "lugarEscenario")
private String lugarEscenario;
#Column(name = "recursoEscenario")
private String recursoEscenario;
#Column(name = "restriccionEscenario")
private String restriccionEscenario;
#Column(name = "actoresEscenario")
private String actoresEscenario;
#ManyToMany(mappedBy = "especificacionEscenarioList", fetch = FetchType.LAZY)
private List<Episodio> episodioList;
}
EspecificacionEscenario especificacionEscenario = new EspecificacionEscenario();
especificacionEscenario.setCodigo("ee-01");
List<EspecificacionEscenario> especificacionEscenarios = new ArrayList<>();
especificacionEscenarios.add(especificacionEscenario);
Episodio episodio = new Episodio();
episodio.setCodigo("e01");
episodio.setDescripcionEpisodio("descripcion episodio");
episodio.setEspecificacionEscenarioList(especificacionEscenarios);
episodioRepo.save(episodio);
I created my app using JHipster. When i try to get list of tournaments via TournamentQueryService i get this error :
Exception in TournamentQueryService.findByCriteria() with cause =
'org.hibernate.HibernateException: Unable to access lob stream' and
exception = 'Unable to access lob stream; nested exception is
org.hibernate.HibernateException: Unable to access lob stream'
This is filter and Page object :
find by criteria : TournamentCriteria{}, page: Page request [number:
0, size 8, sort: startDate: DESC]
So it just gets 8 first tournaments.
This is tournament class :
#Entity
#Table(name = "tournament")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#Document(indexName = "tournament")
public class Tournament extends AbstractAuditingEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
#SequenceGenerator(name = "sequenceGenerator")
private Long id;
#Column(name = "name")
private String name;
#Column(name = "location")
private String location;
#Column(name = "url")
private String url;
#Column(name = "start_date")
private ZonedDateTime startDate;
#Column(name = "end_date")
private ZonedDateTime endDate;
#Column(name = "entry_fee")
private Double entryFee;
#Column(name = "prize")
private Double prize;
#Column(name = "goods")
private String goods;
#Column(name = "favorite_rating")
private Long favoriteRating;
#Column(name = "participants_number")
private Integer participantsNumber;
#Column(name = "finished")
private Boolean finished;
#Column(name = "view_only")
private Boolean viewOnly;
#Column(name = "image")
private String image;
#Column(name = "description")
private String description;
#Column(name = "teams_applied")
private String teamsApplied;
#Lob
#Column(name = "schedule")
private String schedule;
#Lob
#Column(name = "prize_distribution")
private String prizeDistribution;
#Lob
#Column(name = "contacts")
private String contacts;
#Lob
#Column(name = "rules")
private String rules;
#OneToMany(mappedBy = "tournament", fetch = FetchType.LAZY)
#JsonIgnore
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Stream> streams = new HashSet<>();
#ManyToMany(fetch = FetchType.EAGER)
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
#JoinTable(name = "tournament_platforms", joinColumns = #JoinColumn(name = "tournaments_id", referencedColumnName = "id"), inverseJoinColumns = #JoinColumn(name = "platforms_id", referencedColumnName = "id"))
private Set<Platform> platforms = new HashSet<>();
#ManyToOne
private Game game;
#ManyToOne
private TournamentStatus status;
#ManyToOne(fetch = FetchType.LAZY)
private EntryType entryType;
#ManyToOne(fetch = FetchType.LAZY)
private TournamentFormat format;
#ManyToOne
private Region region;
#ManyToOne(fetch = FetchType.LAZY)
private GameMode gameMode;
#ManyToOne(fetch = FetchType.LAZY)
private PrizeType prizeType;
#ManyToOne
private Organizer organizer;
#ManyToOne(fetch = FetchType.LAZY)
private TournamentStage stage;
#ManyToOne
private HostPlatform hostPlatforms;
#ManyToOne(fetch = FetchType.LAZY)
private TournamentType type;
#ManyToOne
private PlayType playType;
#ManyToOne
private Currency currency;
#ManyToOne
private Country country;
Here is the method that calls hibernate :
#Transactional(readOnly = true)
public Page<Tournament> findByCriteria(TournamentCriteria criteria, Pageable page) {
log.info("find by criteria : {}, page: {}", criteria, page);
final Specifications<Tournament> specification = createSpecification(criteria);
Page<Tournament> result = tournamentRepository.findAll(specification, page);
return result;
}
Is it possibile that you are trying to access Lob properties when hiberante session is closed?
Try to replace your #Lob properties with the following:
#Basic(fetch=FetchType.EAGER) #Lob
and check if the error persists.
This is my controller that called it from a class called demand that I want to get the states counter for its id
#SuppressWarnings({ "rawtypes", "unchecked" })
#CrossOrigin("http://localhost:8080")
#RequestMapping(value = "countestado", method = RequestMethod.GET)
public List<Demanda> listadoxcount() {
// String hql = " SELECT d.Estado_Demanda.nombre , con cat(COUNT(d.Estado_Demanda.id) as total ,'-' ,d.Estado_Demanda.nombre ) FROM Demanda d group by d.Estado_Demanda.id ";
String hql = " SELECT d.Estado_Demanda.nombre , COUNT(d.Estado_Demanda.id) as total \r\n" +
"FROM Demanda d \r\n" +
"GROUP BY d.Estado_Demanda.id \r\n" +
"HAVING COUNT(d.Estado_Demanda.id) > 4";
return EntityManager.createQuery(hql).getResultList() ;
}
Here is where I have my class bean, entity or model as you know
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id_demanda")
private int id;
#ManyToOne
#JoinColumn(name = "id_personas", referencedColumnName = "id")
private Persona personas;
#ManyToOne
#JoinColumn(name = "id_estado_demanda", referencedColumnName = "id")
private Estado_Demanda Estado_Demanda;
#Temporal(TemporalType.TIMESTAMP)
#Column
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/mm/yyyy hh:mm:ss")
private Date fecha_registro;
#Column
private String comentario;
#Column
private String descripcion;
#Temporal(TemporalType.TIMESTAMP)
#Column
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/mm/yyyy hh:mm:ss")
private Date fecha_entregada_solicitada;
#Temporal(TemporalType.TIMESTAMP)
#Column
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy hh:mm:ss")
private Date fecha_entrega_comprometida;
#ManyToOne
#JoinColumn(name = "id_tipo_prioridad", referencedColumnName = "id")
private Tipo_prioridade tipo_prioridade;
#Column
private int urgente;
#ManyToOne
#JoinColumn(name = "id_tipo_trama", referencedColumnName = "id")
private Tipo_trama tipo_trama;
#ManyToOne
#JoinColumn(name = "id_tipo_capa_red", referencedColumnName = "id")
private Tipo_capa_red tipo_capa_red;
#ManyToOne
#JoinColumn(name = "id_frame_rate", referencedColumnName = "id")
private FrameRate frameRate;
#ManyToOne
#JoinColumn(name = "id_elemento_red_origen", referencedColumnName = "id")
private Elemento_red elemento_origen;
#Column
private String interfaz_ip_origen;
#ManyToOne
#JoinColumn(name = "id_elemento_red_destino", referencedColumnName = "id")
private Elemento_red elemento_destino;
#Column
private String interfaz_ip_destino;
#OneToMany(cascade = CascadeType.ALL)
#JoinColumn(name = "id_demanda", referencedColumnName = "id_demanda")
private List<FlujoDemanda> flujoDemandas;
//Getters and Setters de Demanda
//Estado_demanda entidad
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
#Column
private String nombre;
#Column
private int activo;
and this is where I have the result of my json where I don't understand how I can do my accountant that is look like a object please help meeeeeeeeee
[
[
"cancelada",
254
],
[
"en proceso",
109
],
[
"entregada",
574
],
[
"registrada",
476
],
[
"cerrrado",
5
]
]