如何处理具有EmbeddedId的实体上的ManyToOne关系的发布请求?

时间:2019-04-01 09:48:11

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

我有一个带有pom.xml定义的休息服务:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-rest</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <scope>runtime</scope>
    </dependency>

我也有一个Store实体:

@Data
@Entity
@FieldDefaults(level = AccessLevel.PRIVATE)
@Table(name = "magasin")
@Inheritance(strategy = InheritanceType.JOINED)
public class Store implements Serializable {

    @EmbeddedId
    StoreId storeId;

    @Column(name = "nom")
    String name;

    @MapsId("businessUnitId")
    @ManyToOne
    @JoinColumn(name = "bu_id", referencedColumnName = "id")
    BusinessUnit businessUnit;

可嵌入的商店ID:

@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
@Embeddable
public class StoreId implements Serializable {

    @Column(name = "id")
    Long id;

    @Column(name = "bu_id")
    Long businessUnitId;

使用以下backendIdConverter:

@Component
public class StoreIdConverter implements BackendIdConverter {

    @Override
    public Serializable fromRequestId(String id, Class<?> entity) {

        if(id != null) {
            String[] param = id.split("_");
            if (entity.getTypeName().equals(Store.class.getTypeName())) {
                StoreId storeId = new StoreId();
                storeId.setId(Long.valueOf(param[0]));
                storeId.setBusinessUnitId(Long.valueOf(param[1]));
                return storeId;
            }
        }
        return id;
    }

    @Override
    public String toRequestId(Serializable id, Class<?> entity) {
        if(entity.getTypeName().equals(Store.class.getTypeName())){
            StoreId storeId = (StoreId)id;
            return String.format("%s_%s", storeId.getId(), storeId.getBusinessUnitId());
        }
        return id.toString();
    }

    @Override
    public boolean supports(Class<?> entity) {
        return true;
    }

这时,我可以使用以下网址执行请求,而不会出现任何问题:     http://localhost:9001/stores/1_1

资源返回:

{
  "storeId" : {
    "id" : 11,
    "businessUnitId" : 1
  },
  "name" : "TEST",
  "_links" : {
    "self" : {
      "href" : "http://localhost:9001/stores/11_1"
    },
    "store" : {
      "href" : "http://localhost:9001/stores/11_1"
    },
    "businessUnit" : {
      "href" : "http://localhost:9001/stores/11_1/businessUnit"
    }
  }
}

但是当我将与商店实体的ManyToOne关系包含到另一个这样的实体中时:

@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
@Entity
@Table(name = "sms")
@SequenceGenerator(name = "SmsSeq", sequenceName = "sms_seq", allocationSize = 1)
@Inheritance(strategy = InheritanceType.JOINED)
public class Sms implements Serializable {

    @Id
    @GeneratedValue(generator = "SmsSeq", strategy = GenerationType.SEQUENCE)
    @Column(name = "id", nullable = false)
    Long id;

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

    @ManyToOne(targetEntity = Store.class)
    @JoinColumns({
        @JoinColumn(name = "magasin_id", referencedColumnName = "id", nullable = false),
        @JoinColumn(name = "bu_id", referencedColumnName = "bu_id", nullable = false)
    })
    Store store;
}

发布请求     http://localhost:9001/smses

{
"message": "Bonjour",
"store": "http://10.1.3.38:9001/stores/1_1"
}

抛出这种异常:

RepositoryRestExceptionHandler : JSON parse error: No converter found capable of converting from type [java.lang.String] to type [com.test.model.StoreId]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: No converter found capable of converting from type [java.lang.String] to type [com.test.model.StoreId] (through reference chain: com.test.model.Sms["store"])

我了解BackendIdConverter不会解析与商店关联的url,是否可以在Request正文上实现相同的目标?

0 个答案:

没有答案