Hibernate: сохранение объекта с внешним первичным ключом - PullRequest
0 голосов
/ 14 февраля 2020

У меня есть база данных с двумя сущностями ( Продукт и Обратная связь ). Обратная связь имеет единственный внешний ключ, который относится к продукту, первичный ключ которого является целым числом. Поэтому они имеют отношение один к одному .

Я хочу добавить новую запись Feedback в базу данных с моим веб-приложением. Для этого я пытаюсь выполнить PUT-запрос к моему Spring-серверу из моего Angular клиентского приложения.

У клиента есть объект класса Feedback со следующими атрибутами (содержимое Feedback.ts)

export class Feedback {
  constructor(
    public productId: number,
    public score: number,
    public preferred: boolean,
    public textNote: string
  ) {
  }
}

Класс Feedback.java на стороне сервера:

@Entity
@Table(name = "feedback")
public class Feedback implements Serializable {
    @Id
    @JoinColumn(name = "product", unique = true)
    @OneToOne(cascade = CascadeType.ALL)
    private Product product;

    @Column(name = "score")
    private double score;

    @Column(name = "preferred")
    private boolean preferred;

    @Column(name = "textnote")
    private String textNote;

    // ... getters, setters, constructor

}

Как видите, существует несоответствующий атрибут: productId is number, а product класса Product. Как я могу дать приложению Spring правильный объект для save его в базе данных?

Я пытаюсь следовать рекомендациям Hibernate и, насколько я понял, это было бы плохой практикой для использования атрибут в java классе типа int вместо Product. Что мне делать?

Ответы [ 3 ]

2 голосов
/ 14 февраля 2020

Вы создаете новый продукт с идентификатором продукта из FE. Теперь вы можете создать новый объект Feedback со всеми установленными типами. Это вы можете затем сохранить в базе данных.

[Edit]

Обычно у вас есть объект передачи данных (DTO) в бэкэнде. Те, как следует из названия, транспортные данные больше ничего не делают. Конечные точки в бэкэнде всегда получат DTO, такие же, как в FE. В вашем случае создайте FeedbackDto.

public class FeedbackDto {
   Long productId;
   Double score;
   Boolean preferred;
   String textNote;
}

Конечная точка получит этот объект, который имеет те же поля, что и обратная связь от FE. Spring создаст и заполнит вас объектом из значений в JSON теле запроса

. В FeedbackD вы теперь создаете сущность Feedback:

new Feedback(new Product(feedbackDto.productId), feedbackDto.score, feedbackDto.preferred, feedbackDto.textNote)

Теперь вы можете сохранить это Обратная связь сущности в вашу базу данных.

1 голос
/ 14 февраля 2020

У меня была такая же проблема, как и у вас, и эта запись в блоге помогла мне решить ее: https://www.baeldung.com/spring-data-rest-relationships. Это работает очень хорошо, если вы также используете Spring Data REST, но я думаю, что вы можете адаптировать его к своему использованию.

По сути, после создания вашей записи Feedback (с первоначальным запросом POST) вы должны выполнить еще один запрос PUT, чтобы связать запись Feedback с вашим Product. Например, у вас может быть что-то вроде:

curl -i -X PUT 
 -d "http://localhost:8080/feedback/1" 
 -H "Content-Type:text/uri-list" http://localhost:8080/product/1/feedbackProduct
0 голосов
/ 14 февраля 2020

Вы можете расширить DefaultConversionService и реализовать собственный конвертер для преобразования идентификатора в продукт

 @Configuration
 public static class Config {
   @Bean
   public ConversionService conversionService () {
      DefaultConversionService service = new DefaultConversionService();
      service.addConverter(new IdToProductConverter());
      return service;
   }
 }

Тогда IdToProductConverter получит идентификатор и сможет искать продукт из БД

class IdToProductConverter implements Converter<String, Product> {
    @Override
    public Product convert(String source) {
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...