Reputation: 756
Using spring data jpa 2.7.5
Here are my entity relations -
@Entity
pubic class ParentEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "parent_id", unique = true, nullable = false, precision = 10)
private BigDecimal parentId;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "parent_id")
private Set<ChildEntity> children;
}
@Entity
pubic class ChildEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "child_id", unique = true, nullable = false, precision = 10)
private BigDecimal childId;
..other fields
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "child_id", referencedColumnName = "child_id", nullable = false)
private Grandchild grandchild;
}
@Entity
pubic class Grandchild{
@Id
@Column(name = "child_id", unique = true, nullable = false, precision = 10)
private BigDecimal childId;
@Column(name = "grandchild_name", length = 60)
private String grandchild_name;
@Column(name = "grandchild_field", length = 60)
private String grandchild_field;
}
The above class declaration gives an error - does not define an IdClass
So I modified my Entity to have an EmbeddableId with one column which is the primaty key and the foreign key childId as below -
@Entity
pubic class Grandchild{
@EmbeddedId
private GrandchildId grandchildId;
@OneToOne(fetch = FetchType.LAZY)
private ChildEntity childEntity ;
@Column(name = "grandchild_name", length = 60)
private String grandchild_name;
@Column(name = "grandchild_field", length = 60)
private String grandchild_field;
}
and the ID class -
@Embeddable
public class GrandchildId implements Serializable {
@Column(name = "child_id", unique = true, nullable = false, precision = 10)
private BigDecimal childId;
}
Now in the service I am trying to build and save parent with all its children and grandchild in a single transaction, with a single save statement building each child and adding it to set of children.
The issue is while trying to save parent in a single save statement (which is a requirement), despite maintaining the proper Cascading types, it complained of null value for childId - the primary key of Grandchild (Also the FK from ChildEntity)
Here is what I am trying to do.
Grandchild gc = new Grandchild();
gc.setGrandchildName("abc");
gc.setGrandChildField("field");
ChildEntity c = new ChildEntity();
c.setGrandChild(gc);
gc.setChild(c);
Set<ChildEntity> childSet;
childSet.add(c)
ParentEntity p = new ParentEntity();
p.setChildren(childSet);
parentRepository.save(p);
nested exception is org.springframework.orm.jpa.JpaSystemException: ids for this class must be manually assigned before calling save(): myPackage.model.Grandchild; nested exception is org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): myPackage.model.Grandchild] with root cause org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save():
I also tried setting the child using @PostPersist on a Child method, but it errors out with NPE before reaching there.
The accepted answer for below question says I dont need to explicitly save the enities but the null id error doesnt budge, I am looking still to call the save method only once -https://stackoverflow.com/questions/16380008/persist-onetoone-relation-with-springdata-jpa
Is there a way I can still do it in a single save? If not what are the alternatives?
Thanks!
Upvotes: 0
Views: 63