Spring数据休息和jpa @OneToMany重复“_links”
Posted
技术标签:
【中文标题】Spring数据休息和jpa @OneToMany重复“_links”【英文标题】:Spring data rest and jpa @OneToMany duplicates "_links" 【发布时间】:2017-07-11 05:43:26 【问题描述】:Spring Data Rest 与 Spring Data JPA 一起使用时遇到问题。我正在使用 Spring-boot 1.4.4.RELEASE。
这是我的 spring-data-rest 存储库:
public interface ProfileJpaRepository extends JpaRepository<Profile, Long>
这是我的实体(为简洁起见,未显示 getter 和 setter)。
Profile.java:
@Entity
@Table(name = "PROFILE")
public class Profile
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String description;
// Don't use mappedBy="profile" because attributes are not persisted properly
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "PROFILE_ID")
private Set<Attribute> attributes;
...
属性.java
@Entity
@Table(name = "ATTRIBUTE")
public class Attribute
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "ID")
private Long id;
private String uri;
@ManyToOne(fetch = FetchType.EAGER)
private Profile profile;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name="ATTRIBUTE_DATAS")
private List<String> datas = new ArrayList<>();
public Attribute()
public Attribute(String uri, List<String> datas)
this.uri = uri;
this.datas = datas;
...
“http://localhost:8880/profiles”上的 POST 以创建实体:
"description" : "description-value",
"attributes" : [
"uri" : "uri-a",
"datas" : ["uri-a-value"]
,
"uri" : "uri-b",
"datas" : ["uri-b-value"]
]
这是我点击http://localhost:8880/profiles时的结果:
"_embedded" :
"profiles" : [
"description" : "description-value",
"attributes" : [
"uri" : "uri-a",
"datas" : [ "uri-a-value" ],
"_links" :
"profile" :
"href" : "http://localhost:8880/profiles/1"
,
"uri" : "uri-b",
"datas" : [ "uri-b-value" ],
"_links" :
"profile" :
"href" : "http://localhost:8880/profiles/1"
],
"_links" :
"self" :
"href" : "http://localhost:8880/profiles/1"
,
"profile" :
"href" : "http://localhost:8880/profiles/1"
]
,
"_links" :
"self" :
"href" : "http://localhost:8880/profiles"
,
"profile" :
"href" : "http://localhost:8880/profile/profiles"
,
"page" :
"size" : 20,
"totalElements" : 1,
"totalPages" : 1,
"number" : 0
我认为有一个问题,因为"_links"
在每个属性下都指定了。相反,我会期待这样的事情:
"_embedded" :
"profiles" : [
"description" : "description-value",
"attributes" : [
"uri" : "uri-a",
"datas" : [ "uri-a-value" ]
,
"uri" : "uri-b",
"datas" : [ "uri-b-value" ]
],
"_links" :
"self" :
"href" : "http://localhost:8880/profiles/1"
,
"profile" :
"href" : "http://localhost:8880/profiles/1"
]
,
"_links" :
"self" :
"href" : "http://localhost:8880/profiles"
,
"profile" :
"href" : "http://localhost:8880/profile/profiles"
,
"page" :
"size" : 20,
"totalElements" : 1,
"totalPages" : 1,
"number" : 0
请注意,我一直在从 MongoRepository 切换到 JpaRepository,并且使用 MongoRepository,这些 "_links"
没有“重复”。
有人可以对此有所了解吗?我是否在我的 JPA 实体上配置错误?我需要在 rest 存储库上配置一些东西吗?
如果您需要,可以在此处找到有关依赖版本的更多信息,我没有覆盖这些 (http://docs.spring.io/spring-boot/docs/1.4.4.RELEASE/reference/html/appendix-dependency-versions.html)
谢谢。
【问题讨论】:
您知道在您的代码中如何/为什么生成 _links 吗?我假设这发生在 JSON 序列化期间,但我从未使用默认配置遇到过它们。 @TorstenN.,这是由 ProfileJpaRepository 自动完成的,Spring Data Rest 看到它扩展了 JpaRepository 并且它“使用 HAL 作为媒体类型为您的域模型公开一个可发现的 REST API”,自动。 【参考方案1】:为了解决我一直在使用 Projections 的问题(更多信息在这里:http://docs.spring.io/spring-data/rest/docs/current/reference/html/#projections-excerpts)。发布时我不知道该功能。
我必须注释我的存储库并告诉它使用我的 InlineAttributes 投影:
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
@RepositoryRestResource(excerptProjection = InlineAttributes.class)
public interface ProfileJpaRepository extends JpaRepository<Profile, Long>
在 Attribute 类上我必须添加 @JsonIgnore 注释:
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
@Table(name = "ATTRIBUTE")
public class Attribute
...
@ManyToOne(fetch = FetchType.EAGER)
@JsonIgnore
private Profile profile;
...
还有我必须创建的 InlineAttributes 投影类。我指定了顺序,因为它与以前不同:
import org.springframework.data.rest.core.config.Projection;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@Projection(name = "inlineAttributes", types = Profile.class )
@JsonPropertyOrder( "description", "attributes" )
public interface InlineAttributes
public String getDescription();
public Set<Attribute> getAttributes();
然后您需要在调用其余端点时应用投影:
http://localhost:8880/profiles?projection=inlineAttributes
【讨论】:
以上是关于Spring数据休息和jpa @OneToMany重复“_links”的主要内容,如果未能解决你的问题,请参考以下文章
@OneToMany Spring Boot 2.1.5.RELEASE 中的 Spring Data JPA 没有获取所有数据
在 JPA/Hibernate 中使用 @OnetoMany 的实体中不存在时从数据库中删除子记录(Spring 引导应用程序)