【问题标题】:Spring Data REST javax.persistence.RollbackException: Error while committing the transactionSpring Data REST javax.persistence.RollbackException:提交事务时出错
【发布时间】:2020-07-30 14:12:10
【问题描述】:

我有两个实体:

@Data
@Entity(name = "users")
@NoArgsConstructor
@RequiredArgsConstructor
@EqualsAndHashCode
public User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="id", unique = true, nullable = false)
    private Integer userId;

    private String userName;

    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
    @JoinColumn(name = "user_id")
    @Fetch(value = FetchMode.SUBSELECT)
    private List<Degree> degreeList;

}

@Data
@Entity(name = "degrees")
@NoArgsConstructor
@RequiredArgsConstructor
@EqualsAndHashCode
public Degree {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="id", unique = true, nullable = false)
    private Integer degreeId;

    private String degreeTitle;
}

RestResources 是:

@RepositoryRestResource(collectionResourceRel = "users", path = "users")
public interface UserRestRepository extends CrudRepository<User, Integer> {
}

然后:

@RepositoryRestResource(collectionResourceRel = "degrees", path = "degrees")
public interface DegreeRestRepository extends CrudRepository<Degree, Integer> {
}

我必须使用 https://www.myhost.com/api/users/{userId}/degreeList 端点在 foo 的 barList 中添加新的 bar,如图所示:

但我得到了:

{
    "timestamp": "2020-04-17T05:16:51.520+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction",
    "path": "/api/users/4/degreeList"
}

我搜了一下,发现必须先保存Degree再更新degreeList,请问该怎么做呢

【问题讨论】:

  • 还有其他需要调查的日志吗?
  • 你的意思是StackTrace?
  • 是来自堆栈跟踪的其他信息
  • 你检查你的映射怎么样?对应的度数是多少?
  • @tksilicon 在Degree 中没有任何@ManyToOne 映射!

标签: spring spring-boot spring-data-jpa spring-data spring-data-rest


【解决方案1】:

Spring Data REST 是基于 URI 的(遵循 HATEOAS 规则)。如果要将“degree”添加到“degreeList”中,确实首先需要创建degree:

HTTP POST 到https://www.myhost.com/api/degrees

请求正文必须是内容类型application/json

之后,您会在响应中取回学位 ID。您使用此 ID 将度数添加到列表中:

HTTP POST 到https://www.myhost.com/api/users/{userId}/degreeList

重要:这次请求的内容类型是text/uri-list!正文必须是纯文本,并且应该只包含 URI

https://www.myhost.com/api/degrees/{degreeId}

【讨论】:

  • 如果我在https://www.myhost.com/api/users/45/degreeList 发出类似{ "href": "https://www.myhost.com/api/degrees/41" } 的帖子请求,它不会添加新的学位,也会清除列表中之前添加的学位。
  • https://www.myhost.com/api/degrees 我正在成功保存新学位!
  • { "href": "myhost.com/api/degrees/41" } 不是正确的请求正文格式。这个在 application/json 中,而您只需要使用我的回答中描述的纯文本:)。只需在请求正文中使用 URL 字符串并将 Content-Type 指定为 type/uri-list。然后就可以正常工作了。
猜你喜欢
  • 1970-01-01
  • 2022-07-16
  • 2019-04-09
  • 1970-01-01
  • 2021-09-02
  • 1970-01-01
  • 2015-11-07
  • 2020-05-11
  • 2016-06-05
相关资源
最近更新 更多