我知道这已经很多次了,我知道这是因为我已经搜索了我的问题以找到解决方案的每个相关问题,但是,没有一个建议的解决方案对我有用,我很确定我必须缺少某些东西。
人类课程:
@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;
}
项目类:
@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;
}
我有一个双向onetomany/许多人的关系,我尝试更改级联类型要持续,添加"可选= false"和更多的东西,但似乎没有任何作用。
我读到我必须在坚持之前手动"加入"实体,这就是我所做的:
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;
但我仍然明白:
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)
老实说,我不知道我缺少什么,如果有人有任何建议,我会很乐意尝试一下。
非常感谢!
解决方案
我设法通过所有建议解决了问题,基本上,我错过了我删除的@GeneratedValue(strategy=GenerationType.AUTO)
注释,因为我认为它不起作用,但是它不起作用,因为我缺少持久性的财产.xml:
<property name="hibernate.id.new_generator_mappings" value="false" />
我在这里找到了此信息
您还需要一种方法来添加对象中的关系:
public void addToProjects(ProjectEntity project){
project.setPersonid(this);
this.projects.add(project);
}
要使这项工作在声明变量时需要初始化列表:
private List<ProjectEntity> projects = new ArrayList<ProjectEntity>();
就是这样!
这是最终的工作代码,以防任何人都发现它有用:(:
人类课程:
@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);
}
}
项目类:
@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;
}
}
确保您将孩子添加到他们的父母中,反之亦然(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();
希望它有帮助!非常感谢。
您要注意的主要因素是正确定义关系的 home side 。据我所记得的,我(有时难以理解的(正式文档的收获是,自有方面几乎是默认情况下触发级联和透明删除的方面。
例如,在上面,您将自己的方面定义为ProjectEntity
,因此级联持久性工作的最重要步骤是将项目添加到PersonEntity.projects
中。
然后,您将要在关系的自有侧拨打persist
,即
em.persist(projectTest);
如果这无济于事,我建议您启用SQL记录您的JPA提供商以找出它要执行的语句,尤其是在哪个顺序中,这些实体是insert
ED。
还尝试根据现有评论,首先坚持下去。如果这样做,我相信正确的方法是将持续存在的实体添加到关系中,即:
PersonEntity persistedPerson = em.persist(personTest);
projectTest.setPersonId(persistedPerson);
em.persist(projectTest);
我能想到的几个线索,因为我越过这种问题不止一次:
除非您想从Project
进行级联操作来更新您的Person
,否则应删除 @manytoone(cascade = cascadetype.all(从您的personid
属性
尝试更新您的projects
集合而不是创建新的集合,因为如果它已经由Hibernate管理(不需要的是,持久/合并操作将在旧的和新的操作上执行。p>人类课程:
private List<ProjectEntity> projects = new ArrayList<>();
您的代码:
personTest.getProjects().addAll(projects);
我通常更喜欢merge
而不是persist
,因为我发现它更"自然",有时,输出显然不是相同的。
我也有同样的问题。@ManyToOne
没有任何理由和2个课程。我添加了@GeneratedValue(strategy=GenerationType.AUTO)
,但没有解决我的问题。
我还试图重命名课程,清洁,关闭项目,重新启动等,但没有任何工作。最后,我删除了文件(以前制作了一个副本(,并将它们从新的问题中重新创建,这解决了我的问题。我当时是Eclipse 4.8,春季2.5,Groovy 2.5,Java 1.8
更新:不确定问题是什么,无论如何(对于Groovy(检查您的保存方法:Myuserrepo( new Myuser (" username"((,以及您的xxxxxrepo&lt; Myuser ,Integer>,还检查您的文件是否为.groovy(最后一个不应该是问题(
其他更新:如果您要在2个表之间创建关系并使用保存结果,请确保在服务上使用@Transactional
并链接关系字段,例如:
@Transactional
UserAccount save(UserAccount userAccount) {
User user = userRepo.save(new User(userAccount))
UserAccount.setUser(user)
userAccountRepo.save(userAccount)
}