I've two entities in a MySQL DB and I want to realize a bi-directional mapping, with an automatic save of the new child when save a new parent.
MACCHINA (parent) fields: id, marca
PERSONA (child) fields: id, nome, macchina_id (foreign key NOT NULL)
When I save a new MACCHINA, I want also to save a new PERSONA by this JSON:
{
"marca": "string",
"personas": [
{
"nome": "string"
}
]
}
MACCHINA entity:
@Entity
@Table(name = "macchina")
public class Macchina implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Column(name = "marca", nullable = false)
private String marca;
@OneToMany(mappedBy = "macchina", cascade = CascadeType.ALL)
private Set<Persona> personas = new HashSet<>();
// getters and setters ...
}
PERSONA entity:
@Entity
@Table(name = "persona")
public class Persona implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Column(name = "nome", nullable = false)
private String nome;
@ManyToOne(optional = false)
@JoinColumn(name="macchina_id", referencedColumnName = "id", nullable = false)
private Macchina macchina;
// getters and setters ...
}
In this scenario, when I call the JPA repository method .save() on the Macchina entity, I've the exception:
> Caused by:
> com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
> Column 'macchina_id' cannot be null
In this same scenario, I tried to remove in the database, the NotNull constraint to the field "macchina_id" in the Persona table; in this case, the transaction is executed, but the "macchina_id" field in the Persona table, is NULL.
I found a work-around by removing the NotNull constraint to the "macchina_id" in the database (and annotations in the entity) AND by modifying the mapping from parent towards child in this way:
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "macchina_id")
private Set<Persona> personas = new HashSet<>();
I removed "mappedBy" and added the @JoinColumn. In this way it works: Hibernate execute an insert into Macchina, an insert into Persona, and finally an update into Persona (I guess to write/update the macchina_id field).
My goal is to mantain the NotNull properties for the field "macchina_id" in the database; mantain some properties values in the child entity on the mapping field private Macchina macchina;
like @NotNull / nullable = false / @ManyToOne(optional = false) and save the both entities at the same time with the "macchina_id" field validated automatically by Spring/Hibernate, without to write code by hand.
So, there is an automatic way (Spring/Hibernate) to save first the parent and then the children who has a NotNull foreign key towards the parent?
Any suggestion?
Regards, Andrea