Как обработать почтовый запрос с отношением ManyToOne для сущности со встроенным идентификатором? - PullRequest
0 голосов
/ 01 апреля 2019

У меня есть служба отдыха с определением 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;

Встраиваемый идентификатор магазина:

@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;
    }

На данный момент я могу без проблем выполнить запрос со следующим URL: 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, связанный с магазином, есть ли способ достичь той же цели в теле запроса?

...