java - 保存单向一对一子实体时分离的持久化父实体
问题描述
我正在使用 spring boot 为我的第一个应用程序编写一些测试。我使用@MapsId 在用户和老师之间创建了一个单向关系,以便用户和老师的pks 相同。现在我认为由于关系仅在教师部分指定,因此在调用保存操作时不会保存用户。尽管以某种方式将老师(新实体)与耦合用户(保留在数据库中)一起保存时,我得到了一个分离的实体异常。实体的相关部分如下所示:
@Entity
public class Teacher {
@Id
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@MapsId
private User user;
}
并且用户实体没有引用教师类:
@Entity
public class User {
// some fields getters and setters
}
在我的测试中,我首先创建了一个用户:
@Test doSomeUserOperations() {
User user = new User()
// set some user info
userRepository.save(user)
// next i want to couple a teacher entity via a method in the teacher service
Teacher teacher = teacherService.getAndCreateTeacherForUser(user.getId());
}
教师服务如下所示:
@Service
public class TeacherService {
@Autowired TeacherRepository teacherRepo; (both extending JpaRepo)
@Autowired UserRepository userRepo;
public Teacher getAndCreateTeacherForUser(Long userId) {
Teacher newTeacher = new Teacher();
newTeacher.setUser(userRepo.findById(userId).get());
return teacherRepo.save(newTeacher);
}
}
现在在返回线上我得到以下异常跟踪:
org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.dorresteijn.wordteacher.model.User; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.dorresteijn.wordteacher.model.User
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:280)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:225)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:527)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy154.save(Unknown Source)
at
解决方案
答案很简单。您的服务不是事务性的,因此用户的读取与教师的持久性处于不同的事务中。在读取和写入之间,它会分离。将一个 @Transactional 注释放在顶部或手动确保事务性,它将起作用。
推荐阅读
- c++ - 根据是否存在某个功能启用模板
- r - R - 何时添加休息
- c - 要求输入数字直到输入零的算法
- java - Java:应用 += 时有些东西会丢失
- r - 在R中将嵌套的JSON转换为数据框
- python - QSqlTableModel 在 InsertRecord 后进入编辑模式
- python-3.x - itertools.product(np.arange(0.0, 1.1, 0.1), repeat=30) 杀死进程
- macos - 无法使用 docker 启动 kafka 和 zookeeper;端口 9092 和 2181 已分配
- android - 过滤数据库并显示满足 2 个条件的结果
- java - JfreeBarchart X轴标签位置