I want to save a record and its child list with spring boot through postman in a One-to-Many relationship. The child list is saved but they don't take the Id of the parent automatically. How can i force the child to automatically take the id of the parent in Post Request In Postman?
Parent Class
package fdsa.edu.pnu.Model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Data
#Table(name = "Concours")
public class Concours implements Serializable {
#Column(name = "ID", nullable = false, length = 10)
#Id
#GeneratedValue(generator = "PNU_CONCOURS_ID_GENERATOR")
#org.hibernate.annotations.GenericGenerator(name = "PNU_CONCOURS_ID_GENERATOR", strategy = "native")
private Integer id;
#Column(name = "DateDebut", nullable = true)
#Temporal(TemporalType.DATE)
private java.util.Date DateDebut;
#Column(name = "DateFin", nullable = true)
#Temporal(TemporalType.DATE)
private java.util.Date DateFin;
#Column(name = "Description", nullable = true, length = 255)
private String description;
#OneToMany(fetch = FetchType.EAGER, mappedBy = "concours",
cascade = CascadeType.ALL,targetEntity = fdsa.edu.pnu.Model.PlannificationConcours.class)
private List<PlannificationConcours> plannificationConcourses;
}
Child Class
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.io.Serializable;
#Entity
#Data
#AllArgsConstructor
#NoArgsConstructor
#Table(name = "PlannificationConcours")
public class PlannificationConcours implements Serializable {
#Column(name = "ID", nullable = false, length = 10)
#Id
#GeneratedValue(generator = "PNU_PLANNIFICATIONCONCOURS_ID_GENERATOR")
#org.hibernate.annotations.GenericGenerator(name = "PNU_PLANNIFICATIONCONCOURS_ID_GENERATOR", strategy = "native")
private int id;
#ManyToOne(targetEntity = fdsa.edu.pnu.Model.Concours.class, fetch = FetchType.LAZY)
#JoinColumns(value = {#JoinColumn(name = "ConcoursID", referencedColumnName = "ID")}, foreignKey = #ForeignKey(name = "ConcoursPlannificationConCours"))
private Concours concours;
#Column(name = "`Date`", nullable = true)
#Temporal(TemporalType.DATE)
private java.util.Date Date;
#Column(name = "Quotation", nullable = true, length = 10)
private double quotation;
#Column(name = "NoteDePassage", nullable = true, length = 10)
private double noteDePassage;
}```
Screen Shote where the Id of the parent is null
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/LlnhP.png
There are 2 ways to reach it. And this is the minimal setting to do it:
Unidirectional
#Entity
#NoArgsConstructor
#Getter
#Setter
public class Concours {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#OneToMany(cascade = CascadeType.ALL)
#JoinColumn(name = "concours_id") // this line will play the role that passes the parent's id to its children
private List<PlannificationConcours> plannificationConcourses = new ArrayList<>();
}
#Entity
#NoArgsConstructor
#Getter
#Setter
public class PlannificationConcours {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
}
#Test
void saveConcours() {
Concours concours = new Concours();
concours.setPlannificationConcourses(List.of(new PlannificationConcours(), new PlannificationConcours()));
this.concoursRepository.save(concours);
}
This's all you need to propagate the parent's id. But the child won't have the reference to its parent by this way.
Bidirectional
#Entity
#NoArgsConstructor
#Getter
public class Concours {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#OneToMany(mappedBy = "concours" ,cascade = CascadeType.ALL) // mappedBy will create a bidirectional relation for us
private List<PlannificationConcours> plannificationConcourses = new ArrayList<>();
public void addPlannificationConcours(PlannificationConcours child) {
child.setConcours(this); // and don't forget to set the parent instance to the child
this.plannificationConcourses.add(child);
}
}
#Entity
#NoArgsConstructor
#Getter
#Setter
public class PlannificationConcours {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#ManyToOne
private Concours concours;
}
#Test
void saveConcours() {
Concours concours = new Concours();
concours.addPlannificationConcours(new PlannificationConcours());
concours.addPlannificationConcours(new PlannificationConcours());
this.concoursRepository.save(concours);
}
Related
A.class
#Getter
#Entity
#Table(name = "A")
public class A extends JpaEntity<Long> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "aId", nullable = false)
private Long id;
#OneToMany(fetch = FetchType.EAGER)
#JoinColumn(name = "aId")
#Setter
private Set<relationship_table_between_a_and_b> bOfa;
}
relationship_table_between_a_and_b.class
#Entity
#Table(name = "relationship_table_between_a_and_b")
#Getter
public static relationship_table_between_a_and_b extends JpaEntity<relationship_table_between_a_and_b.Id> {
#EmbeddedId
#Setter
private Id id;
#Embeddable
#Getter
public static class Id implements Serializable {
#Setter
#Column(name="aId", nullable = false)
private Long aId;
#Setter
#OneToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name="bId", nullable = false)
private B b;
}
}
B.class
public static B extends JpaEntity<Long> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "bId", nullable = false)
private Long id;
#OneToMany(fetch = FetchType.EAGER)
#JoinTable(
name = "relationship_table_between_b_and_a",
joinColumns = #JoinColumn(name = "bId", nullable = false),
inverseJoinColumns = #JoinColumn(name = "aId", nullable = false))
#Setter
#JsonIgnoreProperties("bOfa")
private List<A> as;
}
I tried several ways but didn't solve the stackoverflowerror
Could not solve the infinite reference that occurs when as of class B refers to bToa of a again.
I want to solve this problem... please help
I'm having problem with mapping two classes with composite keys.
The first class is Product:
#Entity
#Table(name = "Products")
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#SuperBuilder
public class Product {
#EmbeddedId
private ProductKey prodPK;
#Column(name = "name", length = 50, nullable = false)
private String name;
#Column(name = "description", length = 80)
private String description;
#Column(name = "totalStock", columnDefinition = "double(8,2) default 0")
private double totalStock;
#ManyToOne
#JoinColumn(name = "companyId", referencedColumnName = "id", nullable = false)
private Company company;
}
With this #EmbeddedId:
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#EqualsAndHashCode
#Embeddable
public class ProductKey implements Serializable {
#Column(name = "sku", length = 50)
private String sku;
#Embedded
private LotKey lot;
}
At the same time, this embedded class has as part of its composite key another composite key "LotKey"
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#EqualsAndHashCode
#Embeddable
public class LotKey implements Serializable {
#Column(name = "lot")
private String lot;
#ManyToOne
#JoinColumn(name = "company", referencedColumnName = "id")
private Company company;
}
which belongs to the class:
#Entity
#Table(name = "Lots")
#Getter
#Setter
#AllArgsConstructor
#NoArgsConstructor
#SuperBuilder
public class Lote {
#EmbeddedId
private LotKey lotpk;
#Column(name = "stock")
private double stock;
#Column(name = "expirationDate", columnDefinition = "default current_timestamp()")
private Date expirationDate;
}
But I'm having trouble referencing to them:
#Entity
#Table(name = "quantityProduct")
public class QuantityProduct{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private long id;
#ManyToOne
#JoinColumns({
#JoinColumn(
name = "sku",
referencedColumnName = "sku"),
#JoinColumn(
name = "lot")
})
private Product product;
#Column(name = "quantity", columnDefinition = "double(8,2) default 0")
private double quantity;
}
I am getting the following error
image
Thank you so much !
In QuantityProduct, set also referencedColumnName in
#JoinColumn(
name = "lot")
I have the following class structure
#Entity
#Data // lombok
public class Entity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "entity_details_id", referencedColumnName = "id")
#JsonManagedReference(value = "entityDetails")
private EntityDetails entityDetails;
}
#Entity
#Data
public class EntityDetails {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#OneToOne(mappedBy = "entityDetails")
#JsonBackReference(value = "entityDetails")
private Entity entity;
// Some more fields
#OneToMany(mappedBy = "entityDetails", cascade = CascadeType.ALL, orphanRemoval = true)
#JsonManagedReference(value = "childEntityDetails")
private List<Child> childList;
}
#Entity
#Data
public class Child {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "description")
private String description;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "entity_details_id")
#JsonBackReference(value = "childEntityDetails)
private EntityDetails entityDetails;
}
Assume I have an Entity object with the following structure:
Entity{
id: null,
entityDetails: {
id: null,
childList: [
{ id: null, description: "ch1" },
{ id: null, description: "ch2" }
]
}
}
When I call entityRepository.save(entity), all the objects are persisted, but the Child table does not have a value for entity_details_id. The other values are correct (I do have Entity.entity_details_id correctly set), but this one does not work. I'm not sure if I'm missing something or if I'm just doing it wrong.
I am working on mapping a relationship using a composite key, but the composite key is a separate table.
Car Table
car Id
car description
car Value
SafetyReport Table
safetyReport Id
safetyReport Date
safetyReport Value
CompositeKey CarSafetyReport Table
carid
safetyReportId
One To Many: A car will have many safety reports
JPA:
#Data
#Entity
#Table(name = "CarTable")
public class CarEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "CarId", nullable = false)
private int carId;
#Column(name = "CarDescription", nullable = false)
private String carDescription;
#Column(name = "CarValue", nullable = false)
private String carDescription;
}
#Data
#Entity
#Table(name = "SafetyReport")
public class SafetyReportEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "SafetyReportId", nullable = false)
private int SafetyReportID;
#Column(name = "SafetyReportDate", nullable = false)
private OffsetDataTime date;
#Column(name = "SafetyReportValue", nullable = false)
private String safetyReportValue;
}
#Data
#Entity
#Table(name = "CarSafetyReport")
public class CarSafetyReportEntity implements Serializable {
#EmbeddedId
private CarSafetyReportPk id;
}
#Data
#AllArgsConstructor
#NoArgsConstructor
#Embeddable
public class CarSafetyReportPk implements Serializable {
#Column(name = "CarId", nullable = false)
private int carId;
#Column(name = "SafetyReportId", nullable = false)
private int SafetyReportId;
}
I tried
public class CarEntity {
#OneToMany(mappedBy = "id.carId" )
private List<CarSafetyReportEntity> carSafetyReportEntity;
}
I also tried putting the relationship in the composite key CarSafetyReportPk but i got an error for the annotation #OneToMany in a composite key.
I need to map make #OneToMany association as one entity (#ManyToOne or #OneToOne) which has the latest field
#Entity
#Getter
#Setter
#Table(name = "trips")
public class TripEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "trips_sequence")
#GenericGenerator(name = "trips_sequence",
strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator",
parameters = {
#Parameter(name = "sequence_name", value = "trips_seq"),
#Parameter(name = "initial_value", value = "100"),
#Parameter(name = "increment_size", value = "1")
})
#Column(name = "trip_id")
private Long id;
//Initially it was such mapping:
//#OneToMany(orphanRemoval = true, mappedBy = "trip", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
//private Set<TripTelemetryEntity> tripTelemetry = new HashSet<>();
//Finally I need something like this
//#ManyToOne or #OneToOne
private TripTelemetryEntity lastTripTelemetry;
}
#Entity
#Getter
#Setter
#IdClass(TripTelemetryEntity.TripTelemetryId.class)
#Table(name = "trip_telemetry")
public class TripTelemetryEntity implements Serializable {
#Id
#Column(name = "trip_id")
private Long tripId;
#ManyToOne
#JoinColumn(name = "trip_id", insertable = false, updatable = false)
private TripEntity trip;
#Id
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "occurred_on")
private Date occurredOn;
#Override
public TripTelemetryId getId() {
return new TripTelemetryId(tripId, occurredOn);
}
/**
* This represents a "composite primary key" for the trip_telemetry table.
*/
#Getter
#Setter
#EqualsAndHashCode
#AllArgsConstructor
#NoArgsConstructor
public static class TripTelemetryId implements Serializable {
private static final long serialVersionUID = 1L;
protected Long tripId;
protected Date occurredOn;
}
}
if I add
#JoinFormula("(SELECT r.id FROM trip_telemetry r WHERE r.trip_id = trip_id ORDER BY r.occurred_on DESC LIMIT 1)")
so I catch exception:
Caused by: org.hibernate.AnnotationException: A Foreign key refering com.app.core.domain.TripTelemetryEntity from com.app.core.domain.TripEntity has the wrong number of column. should be 2
If I do so:
#ManyToOne
#Where(clause = "occurred_on = now()")
private TripTelemetryEntity tripTelemetry;
I catch exception:
org.postgresql.util.PSQLException: ERROR: column tripentity0_.triptelemetry_occurred_on does not exist