2017-02-21 43 views
2

我有一個問題與彈簧數據休息正在使用彈簧數據JPA。我正在使用Spring-boot 1.4.4.RELEASE。春天的數據休息和jpa @OneToMany重複「_links」

這裏是我的春天 - 數據倉庫休息:

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; 

    ... 
} 

Attribute.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實體上配置了錯誤的東西嗎?我需要在其他資源庫上配置什麼嗎?

約依賴版本的更多信息可以在這裏找到你需要它,我沒有覆蓋這些(http://docs.spring.io/spring-boot/docs/1.4.4.RELEASE/reference/html/appendix-dependency-versions.html

感謝。

+0

你知道如何/爲什麼_links在你的代碼中生成?我假設這發生在JSON序列化期間,但我從來沒有遇到過使用默認配置。 –

+2

@TorstenN。,這是由ProfileJpaRepository自動完成的,Spring Data Rest發現它擴展了JpaRepository,並且它自動地「使用HAL作爲媒體類型」爲您的域模型公開了一個可發現的REST API。 – Nis

回答

0

爲了解決我一直在使用投影的問題(更多信息請點擊: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> { 
} 

在屬性類,我不得不添加@JsonIgnore註釋:

import com.fasterxml.jackson.annotation.JsonIgnore; 

@Entity 
@Table(name = "ATTRIBUTE") 
public class Attribute { 
    ... 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JsonIgnore 
    private Profile profile; 

    ... 
} 

而且InlineAttributes投影我必須創建課程。我指定的順序,因爲它是不是和以前一樣:您需要申請當你調用REST端點投影

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