【问题标题】:How to use Spring Data REST and ConversionService using @EmbeddedId?如何使用 @EmbeddedId 使用 Spring Data REST 和 ConversionService?
【发布时间】:2016-08-02 21:35:13
【问题描述】:

我有一个带有 Spring Data REST 的应用程序,它返回这个 JSON:

{
  "_embedded" : {
    "persons" : [ {
      "personDetail" : {
        "name" : "Alex",
        "surname" : "Red",
        "id" : {
          "group" : "A",
          "subclass" : "1"
        },
        "_links" : {
          "self" : {
            "href" : "https ://localhost:8080/myApp/api/personDetails/A_1"
          }
        }
      }
     }]
    }
}   

当我转到网址时:

https://localhost:8080/myApp/api/personDetails/A_1

或到这个网址:

https://localhost:8080/myApp/api/persons/04ee99a5-1578-400a-84be-d1ca87cda752/personDetail

应用返回此 JSON:

{
  "name" : "Alex",
  "surname" : "Red",
  "_links" : {
    "self" : {
      "href" : "https ://localhost:8080/myApp/api/personDetails/A_1"
    },
    "personDetail" : {
      "href" : "https ://localhost:8080/myApp/api/personDetails/A_1"
    }
  }
}

“id”字段似乎消失了。哪里完结了? 如何才能获得正确的对象投影?

这是 Person 类:

@Entity
@Table
public class Person {
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    @Column(columnDefinition = "BINARY(16)", length = 16)
    private UUID id;

    @ManyToOne(fetch = FetchType.EAGER)
    private PersonDetail personDetail;

    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    public PersonDetail getPersonDetail() {
        return personDetail;
    }

    public void setPersonDetail(PersonDetail personDetail) {
        this.personDetail = personDetail;
    }
}

这是 PersonDetail 类:

@Entity
@Table
public class PersonDetail {
    @EmbeddedId
    private PersonDetailId id;

    @Column
    private String name;

    @Column
    private String surname;

    public PersonDetailId getId() {
        return id;
    }

    public void setId(PersonDetailId id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    protected String[] getExcludeFieldNames() {
        return null;
    }

    @Override
    public String toString() {
        return ReflectionToStringBuilder.toStringExclude(this, getExcludeFieldNames());
    }
}

这是 PersonDetailId 类:

public class PersonDetailId implements Serializable {

    @Column(name = "group", nullable = false)
    private String group;

    @Column(name = "subclass", nullable = false)
    private String subclass;

    public PersonDetailId() {
        super();
    }

    public PersonDetailId(String group, String subclass) {
        super();
        this.group = group;
        this.subclass = subclass;
    }

    public String getGroup() {
        return group;
    }

    public void setGroup(String group) {
        this.group = group;
    }

    public String getSubclass() {
        return subclass;
    }

    public void setSubclass(String subclass) {
        this.subclass = subclass;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append(group).append("_").append(subclass);
        return builder.toString();
    }

}

这是存储库 REST:

@RepositoryRestResource
public interface PersonDetailRepository extends JpaRepository<PersonDetail, PersonDetailId> {

    @RestResource(exported=false)
    PersonDetail findBySurname(String surname);

}

这是我使用的转换器:

@Component
public class PersonDetailIdConverter implements Converter<String, PersonDetailId> {

    @Autowired
    private PersonDetailRepository personDetailRepository;

    @Override
    public PersonDetailId convert(String source) {

        PersonDetailId result = null;

        List<PersonDetail> details = personDetailRepository.findAll();
        for (PersonDetail detail:details) {
            if (detail.getId().toString().equals(source)) {
                result = detail.getId();
                break;
            }
        }

        return result;
    }

}

这是注册该转换器的配置:

@Configuration
public class CustomizedRestMvcConfiguration extends RepositoryRestConfigurerAdapter {

    @Bean
    PersonDetailIdConverter personDetailIdConverter(){
        return new PersonDetailIdConverter();
    }

    @Override
    public void configureConversionService(ConfigurableConversionService conversionService) {
        conversionService.addConverter(personDetailIdConverter());
        super.configureConversionService(conversionService);
    }

}

我使用转换器是因为它是使 url 工作的唯一方法:

"href" : "https://localhost:8080/myApp/api/personDetails/A_1"

有什么想法吗? 谢谢。

编辑

这似乎取决于预测。 当我使用我创建的投影转到对象的链接时,返回的 JSON 包含我需要的所有值。

【问题讨论】:

标签: java spring spring-mvc spring-data-jpa spring-data-rest


【解决方案1】:

由于this issue 其中ResourceSupport.getId() 上有@JsonIgnore 注释,Spring Data REST 不会导出实体的 ID。但是,您可以重命名它们,例如到personId(或者只是重命名你的getter方法)。

还记得expose your IDs,正如 Alessandro C 提到的那样。

【讨论】:

    【解决方案2】:

    从 spring 3.1 开始,这是注册转换器的方法:

    @Import(RepositoryRestMvcConfiguration.class)
    public class CustomizedRestMvcConfiguration implements RepositoryRestConfigurer {
    
        @Override
        public void configureConversionService(ConfigurableConversionService conversionService) {
            conversionService.addConverter(new PersonDetailIdConverter());
            super.configureConversionService(conversionService);
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-02
      • 1970-01-01
      • 2015-02-07
      • 2019-09-16
      • 2012-07-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-16
      相关资源
      最近更新 更多