Как работать с @ManyToMany в Spring с помощью Rest Controller и JSON - PullRequest
0 голосов
/ 17 января 2020

Контекст: Я работаю с Spring Boot в качестве серверной части моего приложения. Все выглядит хорошо до сих пор. У меня есть субъект:

@Entity
@Table(name = "tb_dish")
public class DishEntity extends AuditableEntity {

    private BigDecimal salePrice;
    private String picture;
    private String description;

    @ManyToMany
    @JoinTable(name = "tb_dishes_products")
    private List<ProductEntity> products;

    @ManyToOne
    private CategoryEntity category;

    // getters and setters
}

, который отвечает за привязку моих «блюд» к моим «продуктам». Я написал Службу для хранения сущности Di sh в моей БД:

@Service
public class DishService implements IService<DishEntity> {

    @Autowired
    private DishRepository dishRepository;

    @Override
    public DishEntity create(DishEntity entity) {
        try {           
            return this.dishRepository.save(entity);
        } catch(Exception e) {
            System.out.println(e);
            return null;
        }
    }

    // other methods
}

и, наконец, класса Rest Controller, ответственного за получение HTTP-запроса:

@RestController
@RequestMapping(path = "/apis/dishes")
public class DishController implements IController<DishEntity> {

    @Autowired
    private DishService dishService;

    @Override
    @PostMapping
    public ResponseEntity<?> create(@RequestBody DishEntity entity) {
        DishEntity create = this.dishService.create(entity);

        return ResponseEntity.ok().body(create); 
    }

    // other methods
}

* JSON body выглядит следующим образом:

{
    "salePrice": "30.00",
    "picture": "TBD",
    "description": "The description goes here",
    "category": {
        "id": 32
    },
    "products": [
        {
            "product": {
                "id": 29
            }
        },
        {
            "product": {
                "id": 30
            }
        }
    ]
}

Проблема : я много исследовал на inte rnet, но у меня не было успеха в попытке решить мою проблему. Каждый раз, когда я пытаюсь вставить новое «di sh», генерируется исключение:

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientObjectException: объект ссылается на несохраненный временный экземпляр - сохранить временный экземпляр перед сбросом: br.com.barexpert.entity.ProductEntity; вложенное исключение: java .lang.IllegalStateException: org.hibernate.TransientObjectException: объект ссылается на несохраненный временный экземпляр - сохраните временный экземпляр перед сбросом: br.com.barexpert.entity.ProductEntity

Примечание. «Продукты», которые я пытаюсь связать с «di sh», уже вставлены в мою базу данных.

Я знаю пару вещей :

  1. Объект Transient не является Managed в Hibernate, и сначала мне нужно преобразовать эти переходные объекты в управляемые элементы. Итак, вопрос в том, как я могу сделать это для List? Как сделать объекты List управляемыми, учитывая, что эти элементы уже есть в моей базе данных?

  2. Если я использую свойство CascadeType.ALL, Hibernate вставляет новые продукты, содержащие null ценности. Если я пытаюсь сохранить список товаров, используя saveAll(List<S> entities), происходит то же самое.

Если мой вопрос недостаточно хорош, помогите мне его улучшить!

Спасибо!

1 Ответ

0 голосов
/ 17 января 2020

Я хочу поделиться с вами тем, как я решил свою проблему:

Я изменил свой JSON с:

{
    "salePrice": "30.00",
    "picture": "TBD",
    "description": "The description goes here",
    "category": {
        "id": 32
    },
    "products": [
        {
            "product": {
                "id": 29
            }
        },
        {
            "product": {
                "id": 30
            }
        }
    ]
}

На это:

{
    "salePrice": "30.00",
    "picture": "TBD",
    "description": "The description goes here",
    "category": {
        "id": 32
    },
    "products": [
        {
            "id": 29
        },
        {
            "id": 30
        }
    ]
}

Я не знаю, является ли это лучшей практикой, но она сработала:)

...