Публикация данных формы с вложенным объектом с использованием angularjs и весеннего загрузочного веб-API

Я создаю приложение, используя angularjs и Spring Boot Framework. Я публикую обычную форму для отдыха веб-API, и она работает. Но я не знаю, как опубликовать данные формы с вложенным объектом (например, внешний ключ в другой таблице). Что я пробовал:

JS:

vm.product = {
        id: '',
        name: '',
        price: '',
        detail: '',
        brand:{
            brand_id: ''
        },
        subcategory:{
            subcategory_id: ''
        }
    }
vm.submitForm = function () {

        $http.post("http://localhost:8080/api/products/", vm.product)
            .then(
                function (response) {
                    deferred.resolve(response.data);
                },
                function (errResponse) {
                    console.error('Error while creating Product: ' + errResponse.data.errorMessage);
                    deferred.reject(errResponse);
                }
            );
    }

Форма

<form class="forms-sample" ng-submit="products.submitForm()">
                    <div class="form-group">
                        <label for="exampleInputName1">Name</label>
                        <input type="text" class="form-control" id="exampleInputName1" ng-model="products.product.name"
                            placeholder="Name">
                    </div>
                    <div class="form-group">
                        <label for="exampleInputPassword4">Price</label>
                        <input type="number" class="form-control" id="exampleInputPassword4" ng-model="products.product.price"
                            placeholder="Price">
                    </div>

                    <div class="form-group">
                        <label for="exampleTextarea1">Detail</label>
                        <textarea class="form-control" id="exampleTextarea1" rows="2" ng-model="products.product.detail"></textarea>
                    </div>

                    <div class="form-group">
                        <label for="exampleTextarea1">Brand Id</label>
                        <select ng-model="products.product.brand.brand_id" class="form-control" id="exampleFormControlSelect2">
                            <option>1</option>
                            <option>2</option>
                            <option>3</option>
                            <option>4</option>
                            <option>5</option>
                        </select>
                    </div>

                    <div class="form-group">
                            <label for="exampleTextarea1">Subcategory Id</label>
                            <select ng-model="products.product.subcategory.subcategory_id" class="form-control" id="exampleFormControlSelect2">
                                <option>1</option>
                                <option>2</option>
                                <option>3</option>
                                <option>4</option>
                                <option>5</option>
                            </select>
                        </div>
                    <button type="submit" class="btn btn-success mr-2">Submit</button>
                    <button class="btn btn-light">Cancel</button>
                </form>

Организация:

@Entity
@Table(name = "product")
public class Product implements Serializable {

private static final long serialVersionUID = 1L;

//----------------------------------------------------------------------
// ENTITY PRIMARY KEY 
//----------------------------------------------------------------------
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;


//----------------------------------------------------------------------
// ENTITY DATA FIELDS 
//----------------------------------------------------------------------    
@Column(name = "detail", length = 2147483647)

private String detail;

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

private Double price;
// Attribute "brandId" is a link
// Attribute "subcategoryId" is a link

//----------------------------------------------------------------------
// ENTITY LINKS ( RELATIONSHIP )
//----------------------------------------------------------------------


@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "subcategory_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@JsonBackReference(value = "subcategory _id")
private Subcategory subcategory;


@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "brand_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@JsonBackReference(value = "brand _id")
private Brand brand;


@OneToMany(fetch = FetchType.LAZY, mappedBy = "product")
@JsonManagedReference(value = "product _id")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
private List<Review> listOfReview;


// getters and setters

//----------------------------------------------------------------------
// toString METHOD
//----------------------------------------------------------------------


@Override
public String toString() {
    return "Product{" +
            "id=" + id +
            ", detail='" + detail + '\'' +
            ", image1='" + image1 + '\'' +
            ", image2='" + image2 + '\'' +
            ", image3='" + image3 + '\'' +
            ", name='" + name + '\'' +
            ", price=" + price +
            ", subcategory=" + subcategory +
            ", brand=" + brand +
            '}';
}

}

WEBAPI

@CrossOrigin
@PostMapping("/api/products")
public Product createProduct(@RequestBody Product product) {
    System.out.println("Product: " + product);
    System.out.println("Subcategory: " + product.getSubcategory());
    Product product1 = productRepository.save(product);

    return product1;
}

Кажется, что subcategory_id и brand_id не могут быть проанализированы. В консоли продукт печатается следующим образом:

Product: Product{id=null, detail='asdg', image1='null', image2='null', image3='null', name='dfgfsg', price=3.0, subcategory=null|null, brand=null|null}

Итак, как я могу опубликовать форму с внешним ключом, как это приложение? Я много ищу, но не могу найти решение.

Спасибо


person aptech Luan    schedule 21.01.2019    source источник


Ответы (1)


Похоже, вы пытаетесь спасти Product и его дочерние элементы за один раз.

Для этого вам понадобятся две дополнительные вещи:

1) Включите каскадирование PERSIST:

@ManyToOne(fetch = FetchType.LAZY, optional = false, cascade = CascadeType.PERSIST)
...
private SubCategory subcategory;

2) Если Subcategory имеет ассоциацию @OneToMany с Product, вам нужно будет установить обе стороны отношения:

public Product createProduct(@RequestBody Product product) {
   Subcategory subCat: product.product.getSubcategory();
   subCat.getProducts().add(product);
   Product product1 = productRepository.save(product);

    return product1;
}

Конечно, вам это не нужно, если оно отображается только в Product.

person Maciej Kowalski    schedule 21.01.2019
comment
Я нашел способ решить проблему. Я создал ProductRequestDto для хранения параметров, отправленных от клиента (включая внешний ключ), а затем легко сопоставил его с сущностью Product. Затем я могу сохранить продукт без проблем. Спасибо за Ваш ответ - person aptech Luan; 21.01.2019