I know this has been asked a lot of times before, I know it because I've searched for every related question to my problem to try to find a solution, however, none of the proposed solutions are working for me and I'm pretty sure that I have to be missing something.
Person Class:
@Entity
@Table(name = "person", schema = "test")
public class PersonEntity {
@Id
@Column(name = "id")
private long id;
@Basic
@Column(name = "name")
private String name;
@Basic
@Column(name = "age")
private int age;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "personid")
private List<ProjectEntity> projects;
}
Project Class:
@Entity
@Table(name = "project", schema = "test")
public class ProjectEntity {
@Id
@Column(name = "id")
private long id;
@Basic
@Column(name = "name")
private String name;
@Basic
@Column(name = "budget")
private int budget;
@JoinColumn(name = "personid", referencedColumnName = "id")
@ManyToOne(cascade = CascadeType.ALL)
private PersonEntity personid;
}
I have a bidirectional OneToMany/ManyToOne relationship, I have tried changing the cascade type to PERSIST, adding 'optional=false' and way more things but nothing seems to work.
I read that I have to 'join' manually the entities before the persist, and that's what I did:
em = JPAUtility.getEntityManager();
em.getTransaction().begin();
PersonEntity personTest = new PersonEntity();
personTest.setName("Test");
personTest.setAge(23);
ProjectEntity projectTest = new ProjectEntity();
projectTest.setName("hello");
projectTest.setBudget(232);
projectTest.setPersonid(personTest);
List<ProjectEntity> projects = new ArrayList<ProjectEntity>();
projects.add(projectTest);
personTest.setProjects(projects);
em.persist(personTest);
em.getTransaction().commit();
em.close();
return personTest;
But I still get this:
Caused by:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
Cannot add or update a child row: a foreign key constraint fails
(`test`.`project`, CONSTRAINT `FK_Personid` FOREIGN KEY (`personid`) REFERENCES
`person` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)
I honestly don't know what I'm missing, if anyone has any suggestion I'll be more than happy to try it.
Thank you so much!
SOLUTION
I managed to solve the problem thanks to all the suggestions, basically, I was missing the @GeneratedValue(strategy=GenerationType.AUTO)
annotation which I removed because I thought it didn't work but, it wasn't working because I was missing a property on the persistence.xml:
<property name="hibernate.id.new_generator_mappings" value="false" />
You also need a method to add the relationship in the objects:
public void addToProjects(ProjectEntity project){
project.setPersonid(this);
this.projects.add(project);
}
To make this work you need to initialize the List when you declare the variable:
private List<ProjectEntity> projects = new ArrayList<ProjectEntity>();
And that's it!
This is the final working code in case anyone can find it useful :):
Person Class:
@Entity
@Table(name = "person", schema = "test")
public class PersonEntity {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "id")
private long id;
@Basic
@Column(name = "name")
private String name;
@Basic
@Column(name = "age")
private int age;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "personid")
private List<ProjectEntity> projects = new ArrayList<ProjectEntity>();
public void addToProjects(ProjectEntity project) {
project.setPersonid(this);
this.projects.add(project);
}
}
Project Class:
@Entity
@Table(name = "project", schema = "test")
public class ProjectEntity {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "id")
private long id;
@Basic
@Column(name = "name")
private String name;
@Basic
@Column(name = "budget")
private int budget;
@JoinColumn(name = "personid", referencedColumnName = "id")
@ManyToOne(cascade = CascadeType.PERSIST)
private PersonEntity personid;
public void setPersonid(PersonEntity personid) {
this.personid = personid;
}
}
Make sure you add the Children to their Parent and vice-versa (addToProjects())
em = JPAUtility.getEntityManager();
em.getTransaction().begin();
PersonEntity personTest = new PersonEntity();
personTest.setName("Butters");
personTest.setAge(10);
ProjectEntity projectTest = new ProjectEntity();
projectTest.setName("Hanks");
projectTest.setBudget(10000);
ProjectEntity projectTest2 = new ProjectEntity();
projectTest2.setName("X");
projectTest2.setBudget(100);
personTest.addToProjects(projectTest);
personTest.addToProjects(projectTest2);
em.persist(personTest);
em.getTransaction().commit();
em.close();
Hope it helps! Thank you so much.