Java 分离的实体传递给persist-Spring API-@OneToOne关系
我是Spring的新手,我正在开发一个API,但是上面的错误消息给我带来了麻烦 我有一个@OneToOne关系:Java 分离的实体传递给persist-Spring API-@OneToOne关系,java,spring,Java,Spring,我是Spring的新手,我正在开发一个API,但是上面的错误消息给我带来了麻烦 我有一个@OneToOne关系: @Id @GeneratedValue(策略=GenerationType.IDENTITY) @列(name=“userId”) 私有整数用户标识; 私有字符串名称; 私人字符串电子邮件; 私有字符串密码; @Id @列(name=“contId”) 私有整数contId; @OneToOne(fetch=FetchType.LAZY) @MapsId 私人用户; 专用字符串oc
@Id
@GeneratedValue(策略=GenerationType.IDENTITY)
@列(name=“userId”)
私有整数用户标识;
私有字符串名称;
私人字符串电子邮件;
私有字符串密码;
@Id
@列(name=“contId”)
私有整数contId;
@OneToOne(fetch=FetchType.LAZY)
@MapsId
私人用户;
专用字符串ocupaco;
私密字符串natOcupacao;
私人国际公寓;
私有字符串名称;
私人长期中央公积金;
@列(name=“dataNasc”)
@时态(TemporalType.DATE)
@日期时间格式(pattern=“dd/MM/yyyy”)
私有日期数据NASC;
私有字符串nitPisPasep;
私人内部产权;
私有国际货币基金组织;
我正在尝试使用下面的控制器:
@PostMapping(path=“/”)
公共响应创建(@RequestBody contribute contribute)
抛出URISyntaxException{
Contribuinte createdContribuinte=contRepository.save(Contribuinte);
如果(createdContribuinte==null){
返回ResponseEntity.notFound().build();
}否则{
URI=ServletUriComponentsBuilder.fromCurrentRequest()
.path(“/{id}”)
.buildAndExpand(CreatedContribute.getContId())
.toUri();
返回ResponseEntity.created(uri)
.主体(CreatedContribute);
}
}
相反的:
package com.swcir.swcirsystem.Repositories;
导入com.swcir.swcirsystem.Models.Contribuinte;
导入org.springframework.data.jpa.repository.JpaRepository;
公共接口ContribuiInterepository扩展了JpaRepository{
}
异常的完整堆栈跟踪:
2021-05-29 14:35:23.836错误20012---[nio-8090-exec-2]o.a.c.c.c.[/].[dispatcherServlet]:路径[]上下文中Servlet[dispatcherServlet]的Servlet.service()引发异常[请求处理失败;嵌套异常为org.springframework.dao.InvalidDataAccessApiUsageException:传递给persist的分离实体:com.swcir.swcirsystem.Models.User;嵌套异常为org.hibernate.PersistentObjectException:传递给persist的分离实体:com.swcir.swcirsystem.Models.User],具有根本原因
注:
有什么问题吗?根据异常:contribuinte.user处于分离状态,因此您需要通过用户ID获取持久用户,或者级联持久化用户实体 如果要创建或更改用户cascadingly,在保存contribuinte时,请在contribuinte实体中执行以下操作: 解决方案1:
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@MapsId
private User user;
警告:通常不推荐解决方案1,因为用户是一个独立的实体,有自己的生命周期。我认为使用contRepository.save(contribuinte)管理用户名或用户电子邮件不是一个好主意方法。应该有一个单独的userRepository.save(user)方法。此外,如果UI意外地为contribuinte.getUser().getName()或contribuinte.getUser().getEmail()传递空值,这将删除用户名和userEmail()
解决方案2:
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@MapsId
private User user;
如果您不想创建或更改用户cascadingly,则在保存contribute时,请执行以下操作:
User user = contribuinte.getUser() == null ? null : userRepository.findByUserId(contribuinte.getUser().getUserId());
contribuinte.setUser(user);
Contribuinte createdContribuinte = contRepository.save(contribuinte);
确保上述代码在一个事务中
解决方案2将防止用户被创建或更改,但您需要确保:
- contribuinte.getUser().getUserId()从不为null(除非您想从contribuinte取消分配用户:在这种情况下,contribuinte.getUser()必须为null)
- 解决方案2:将不允许使用contRepository.save(contribuinte)
- 也不可能使用contRepository.save(contribuinte)
- 但可以更改contribuinte的用户,或将其设置为null