POST POST新实体时如何在Spring Data REST中引用具有继承的实体? [英] How to reference an entity with inheritance in Spring Data REST when POSTing new entity?

查看:122
本文介绍了POST POST新实体时如何在Spring Data REST中引用具有继承的实体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有加入继承的实体:

支持者

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "supporterType")
@JsonSubTypes({
    @JsonSubTypes.Type(value = PersonSupporterEntity.class, name = "PERSON"),
    @JsonSubTypes.Type(value = CompanySupporterEntity.class, name = "COMPANY")
})
@DiscriminatorColumn(name="supporter_type")
@Table(name = "supporter")
public class SupporterEntity extends UpdatableEntity {
    private long id;
    private SupporterType supporterType;
    private PartnerEntity partner;
...
}

PersonSupporter

PersonSupporter

@Entity
@DiscriminatorValue("PERSON")
@Table(name = "person_supporter")
public class PersonSupporterEntity extends SupporterEntity {
...
}

CompanySupporter

CompanySupporter

@Entity
@DiscriminatorValue("COMPANY")
@Table(name = "company_supporter")
public class CompanySupporterEntity extends SupporterEntity {
...
}

我有另一个引用SupporterEntity的实体

I have another entity which references SupporterEntity

@Entity
@Table(name = "contact")
public class ContactEntity extends UpdatableEntity {

    private long id;
    private SupporterEntity supporter;
...
    @ManyToOne // same error with @OneToOne
    @JoinColumn(name = "supporter_id", referencedColumnName = "id", nullable = false)
    public SupporterEntity getSupporter() {
        return supporter;
    }
...
}

存储库

@Transactional
@RepositoryRestResource(collectionResourceRel = "supporters", path = "supporters")
public interface SupporterEntityRepository extends JpaRepository<SupporterEntity, Long> {

    @Transactional(readOnly = true)
    @RestResource(path = "by-partner", rel = "by-partner")
    public Page<SupporterEntity> findByPartnerName(@Param("name") String name, Pageable pageable);
}



@Transactional
@RepositoryRestResource(collectionResourceRel = "person_supporters", path = "person_supporters")
public interface PersonSupporterEntityRepository extends JpaRepository<PersonSupporterEntity, Long> {

}



@Transactional
@RepositoryRestResource(collectionResourceRel = "company_supporters", path = "company_supporters")
public interface CompanySupporterEntityRepository extends JpaRepository<CompanySupporterEntity, Long> {

}



@Transactional
@RepositoryRestResource(collectionResourceRel = "contacts", path = "contacts")
public interface ContactEntityRepository extends JpaRepository<ContactEntity, Long> {

    @Transactional(readOnly = true)
    @RestResource(path = "by-supporter", rel = "by-supporter")
    public ContactEntity findBySupporterId(@Param("id") Long id);
}

我使用Spring Boot,Spring Data REST,Spring Data JPA,Hibernate,Jackson 。当我尝试使用这样的帖子请求创建一个新的ContactEntity时:

I use Spring Boot, Spring Data REST, Spring Data JPA, Hibernate, Jackson. When I try to create a new ContactEntity with a post request like this:

{
   "supporter":"/supporters/52",
   "postcode":"1111",
   "city":"Test City 1",
   "address":"Test Address 1",
   "email":"test1@email.com",
   "newsletter":true
}

我得到了这个例外:

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (VALUE_STRING), expected FIELD_NAME: missing property 'supporterType' that is to contain type id  (for class com.facer.domain.supporter.SupporterEntity)
 at [Source: HttpInputOverHTTP@4321c221; line: 1, column: 2] (through reference chain: com.facer.domain.supporter.ContactEntity["supporter"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148) ~[jackson-databind-2.4.4.jar:2.4.4]

2天后调试我发现了一种方法,但我猜对了。所以,如果我这样发布:

After 2 days of debugging I found a way, but I kinda guessed it. So if I post it like this:

{
   "supporter":{
      "supporterType":"PERSON",
      "id":"52"
   },
   "postcode":"1111",
   "city":"Test City 1",
   "address":"Test Address 1",
   "email":"test1@email.com",
   "newsletter":true
}

它有效,但我不知道为什么。其他请求有什么问题?当引用的实体没有继承时,它就像其他地方一样。

It works, but I don't know why. What's wrong with the other request? It works like that everywhere else when the referenced entity does not have inheritance.

推荐答案

使用 RelProvider :


  1. 不要使用 @JsonTypeInfo

  2. SupporterEntity 子类创建 RelProvider

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SupporterEntityRelProvider implements RelProvider {

  @Override
  public String getCollectionResourceRelFor(final Class<?> type) {
    return "supporters";
  }

  @Override
  public String getItemResourceRelFor(final Class<?> type) {
    return "supporter";
  }

  @Override
  public boolean supports(final Class<?> delimiter) {
    return org.apache.commons.lang3.ClassUtils.isAssignable(delimiter, SupporterEntity.class);
  }
}


另见:

  • https://jira.spring.io/browse/DATAREST-344
  • http://docs.spring.io/spring-hateoas/docs/current/reference/html/#configuration.at-enable

这篇关于POST POST新实体时如何在Spring Data REST中引用具有继承的实体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆