我有一个父实体a,它与映射在a_B表和a_C表中的实体B和实体C有多对多关系。在持久化时,我希望只持久化a、a_B和a_C,而不持久化B和C。如果我不使用cascadetype。all i get“object references a unsaved transient instance-save the transient instances before flush”错误。如果我使用cascade。所有的表都会更新。
这是我的父母实体学生(getter和setter存在但未显示)
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int studentId;
......
......
@ManyToMany()
@JoinTable(name = "student_preferredCountry",joinColumns = @JoinColumn(name
= "studentId"),inverseJoinColumns = @JoinColumn(name = "countryId"))
private Set<Country> countries;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "student_preferred_course",joinColumns = @JoinColumn(name
= "studentId"),inverseJoinColumns = @JoinColumn(name = "courseId"))
private Set<Course> courses;
这是我的孩子实体课程
@Entity
public class Course {
private String courseName;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int courseId;
@ManyToMany(mappedBy = "courses")
private List<Student> coursestudents;
这是我的另一个孩子实体国家
@Entity
public class Country {
@Id
private int countryId;
private String countryName;
@ManyToMany(mappedBy = "countries")
private List <Student> students;
这就是我坚持的方式
public boolean studententry(@RequestBody Student stud){
studentRepository.save(stud);
这是示例json请求
{
"studentFname": "fdfd",
"studentMname": "dfdf",
"studentLname": "fdf",
"studentFatherName": "fd",
"studentMotherName": "dfd",
"studentEmail": "dfd",
"studentAddress": "df",
"studentPhone": "df",
"countries": [
{
"countryId": "1",
"countryName": "aus"
},
{
"countryId": "2",
"countryName": "newz"
}
],
"courses": [
{
"course_id": "1",
"course_name": "IELTS"
},
{
"course_id": "2",
"course_name": "TOEFL"
}
]
}
基本上,我想添加所有的学生属性,student_curses,student_stcountry,而不需要坚持课程和国家表
您需要从@ManyToMany
切换到@OneToMany
。
然后,您可以将级联放在< code>Student上,并在< code>StudentCourse和< code>StudentCountry实体中省略它。
唯一的缺点是需要为这些链接表创建中间实体:
学生
@OneToMany(cascade = CascadeType.ALL, mappedBy="student")
private Set<StudentCourse> courses;
选课表
@ManyToOne
private Student student;
@ManyToOne
private Course course;
课程
@Entity
public class Course {
private String courseName;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int courseId;
@ManyToMany(mappedBy = "courses")
private List<StudentCourse> coursestudents;
您需要相应地修改传入的json对象,以支持那些中间实体ofc。
首先,级联=ALL
所做的与您想要的相反。ALL=PERSIST、MERGE、REFRESH、DETACH、REMOVE
,所以它基本上说“每当我存储、更新或删除学生
时,对所有相关的课程
执行相同的操作”,等等。
对于@ManyToMany
关联,PERSIST
、MERGE
和REMOVE
没有多大意义。您可能希望保留 REFRESH
和 DETACH,
但建议您摆脱其余部分。
其次,删除 MERGE
具有获取 TransientObjectException
的副作用。发生这种情况是因为您尝试保存引用其他分离实体的分离实体。您可能正在调用 repository.save(student),
但这只会合并学生
实体,并且引用
的课程实体保持分离状态。
若要解决此问题,需要将分离的实体实例替换为具有相同 id 的托管实体实例:
Set<Courses> managedCourses = new HashSet<>();
for (Course course : stud.getCourses()) {
managedCourses.add(courseRepository.getOne(course.getId()));
}
stud.setCourses(managedCourses);
studentRepository.save(stud); //no TransientObjectException this time!
(注意< code>getOne()在循环中的使用;您可能很想使用< code>findAllById(),认为这样性能会更好,但是< code>getOne()的好处是它不会从数据源获取相关的实体状态。< code>getOne()是由< code>JpaRepository提供的,特别考虑到这个用例:在实体之间建立关联)
最后,我可以看到stud
用@RequestBody
注释,这表明我们在这里是一个Controller
类。对于上述方法,您希望使用@Transactional
将整个方法包装在事务中。由于事务控制器方法不是很好的实践,我建议将studentry
方法的主体提取到单独的@transactional
、@Service
注释bean中。
我是Spring/JPA/Hibernate的新手,虽然听起来很简单,但现实并非如此。我需要一些帮助。 第1轮,我创建一个新的父级和一个新的子级,将子级添加到父级列表中,并在子级上设置父级。我救了父母,孩子也就救了。 现在,第二轮,我添加一个新的孩子: 然而,这一次的新孩子却从来没有坚持过! 通过hibernate(痛苦!)来跟踪这个,我发现了以下内容: 第二次保存时,问题是第二个(新)子级。 问
问题内容: 我们使用的是带有Hazelcast 3.6.1 2级缓存的Hibernate 3.5.6-Final。 情况 我和具有Hibernate设置的实体之间存在双向,一对多关系。实体类定义如下: 父级的Hibernate映射定义如下: 子项的hibernate映射定义如下: 现在,当前代码向中添加了,如下所示: 问题是第二行代码导致Hibernate加载 所有 子代。在我们的设置中,这是一个
情况: 我有两个与OneTomany/ManyToone关系相关的实体。 想象一下,每个类也有一个名为id和getter和setter的PK。 问题: 如果我创建一个EntityA实例并设置一个与已经存在的EntityB实例的关系并持久化这个新实例,那么所有数据都会正确地保存到数据库中。但是,如果我从我的EntityManager请求EntityB的实例,它的列表中将不包含刚刚持久化的Entity
为了理解为什么要持久化子实体,下面是映射。 我有作者(id,姓名,书籍)和书籍(id,标题,作者)实体。他们的关系是很多的,因为任何作者可能有多个书,任何书可能有多个作者。此外,我有BookClient(id,名称,rentDate,books) - 与Book实体的关系是OneToMany,因为任何客户都可以向许多书籍租用零。 Author.java Book.java BookClient.j
尝试获取父实体(Msg)的实体,其中父PK (msg_id)是子实体中的FK时,尝试保持子实体(MsgRetry)时出错。 错误,如:org.hibernate.id.IdentifierGenerationException:试图从null一对一属性分配id 父实体,不需要知道子实体(至少我认为它不需要知道)。一旦子实体被持久化,我就会尝试也持久化父实体。我可以通过在子实体中没有父实体并调用关联
对于新学生和新课程的情况,它工作得很好,但是在新课程和现有学生的情况下,我会从数据库中抛出一个唯一的约束冲突。关系类似于下面。 在持久化之前,我尝试使用entitymanager查找一个学生,如果该学生存在,则使用该实例而不是新的学生实例。这也不起作用,它仍然尝试执行插入而不是更新