Ho un'entità semplice con una singola raccolta mappata.Impossibile postare una raccolta
@Entity
public class Appointment Identifiable<Integer> {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@JsonIgnore
private Integer id;
@Column(name="TRAK_NBR")
private String trackNumber;
@OneToMany(fetch =FetchType.EAGER, cascade= CascadeType.ALL)
@JoinColumn(name="CNSM_APT_VER_WRK_I", nullable = false)
private Set<Product> products = new HashSet<Product>();
}
@Entity
public class Product implements Identifiable<Integer> {
@Id
@Column(name = "CNSM_PRD_VER_WRK_I")
@GeneratedValue(strategy = GenerationType.AUTO)
@JsonIgnore
private Integer id;
@Column(name = "PRD_MDL_NBR")
private String model;
@Column(name = "PRD_SPEC_DSC")
private String description;
}
Nella mia domanda, quando ho includere solo una PagingAndSortingRepository per la nomina. Posso chiamare il comando POST con il seguente carico utile.
{
"trackNumber" : "XYZ123",
"products": [
{"model" : "MODEL",
"description" : "NAME"
}]
}
Quando aggiungo un PagingAndSortingRepository per il prodotto e provo la stessa POST ottengo il seguente messaggio di errore.
{
"cause" : {
"cause" : {
"cause" : null,
"message" : null
},
"message" : "(was java.lang.NullPointerException) (through reference chain: com..model.Appointment[\"products\"])"
},
"message" : "Could not read JSON: (was java.lang.NullPointerException) (through reference chain: com.model.Appointment[\"products\"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.model.AppointmentVerification[\"products\"])"
}
My GET payload with both Repositories returns this. This is my desired format. The link to products should be included
{
"trackNumber" : "XYZ123",
"_links" : {
"self" : {
"href" : "http://localhost:8080/consumerappointment/appointments/70"
},
"products" : {
"href" : "http://localhost:8080/consumerappointment/appointments/70/products"
}
}
Con il solo repository degli appuntamenti ottengo il seguente carico utile e posso pubblicare l'elenco dei prodotti.
{
"trackNumber" : "XYZ123",
"products" : [ {
"model" : "MODEL",
"description" : "NAME",
} ],
"_links" : {
"self" : {
"href" : "http://localhost:8080/consumerappointment/appointments/1"
}
}
}
Vedo, questo non è ovvio dal codice lassù. Naturalmente non sono nei dettagli della progettazione del database, ma una chiave esterna, non significa che debba essere impostata in primo luogo. Potrebbe essere solo il riferimento che lega il prodotto ad un appuntamento più tardi (da qui il tuo 'Set'). Detto questo, ho cercato di spiegare perché funziona come funziona. Totalmente possibile che il modello non corrisponda al tuo caso d'uso ma non puoi dover separare le radici aggregate che hanno una relazione bidirezionale tra loro per definizione. –
La tabella dei prodotti ha un vincolo di chiave esterna nella tabella degli appuntamenti. Quindi creare prodotti prima non funziona. Posso superare il comportamento del POST quando ho entrambi i repository? Devo essere in grado di creare l'appuntamento e i prodotti nella stessa transazione, ma ho ancora il link ai prodotti in GET. – zachariahyoung
Sì, è sufficiente fornire un controller implementato manualmente per il percorso appropriato e il metodo HTTP dovrebbe fare il trucco. Tuttavia, penso che stia mascherando un problema di progettazione fondamentale. –