简体   繁体   中英

Spring JPA - post resource in many to one relationships

This question is closely related to this one (Solving this one here, will probably also solve the other).

In my spring mvc app (github) I have two resources: Cart and Item where a cart can have multiple items.

The CartController maps a POST method which adds a random item to a cart with a given ID

/* Forgetting about response entity and null checking etc. for now */

    @PostMapping("carts/rdm/{id}")
    public Cart addRandomItem(@PathVariable("id") long id)
    {
        String[] rdmItemNames = {"toothbrush", "shampoo", "body wash"};
        int rnd = new Random().nextInt(rdmItemNames.length);
        String itemName = rdmItemNames[rnd];

        // Add new item to the cart with given id
        Cart cart = dao.getById(id);

        Item item = new Item();
        item.setItemName(itemName);

        // This works but I have to create a new cart object with same id
        Cart sameCart = new Cart();
        sameCart.setId(cart.getId());
        item.setCart(sameCart);

        // This doesn't work, no surprise but I would like to
        // just retrieve the Cart, add the new Item and be done.
        // item.setCart(cart);
        // cart.getItems().add(item);
        return dao.save(cart);
    }

After POSTing to http://localhost:9100/carts/rdm/1 , I get the following Cart json

{
    "id": 1,
    "items": [
        {
            "id": 0,
            "itemName": "body wash",
            "cart": {
                "id": 1,
                "items": null
            }
        }
    ]
}

Feels like I am not understanding JPA correctly. This boils down again to why the Item object needs to contain the whole Cart object. If Item only contained the foreign key (the cart id), then I could produce a json like this

   {
        "id": 1,
        "items": [
            {
                "id": 0,
                "itemName": "body wash",
                "cart_id": 1
            }
        ]
    }

JPA is a high level ORM Framework. Which means that the object-references of java are converted to relational references in your Database.

So in your database you will have a foreign key where an item references a car.

JPA converts these relational-relation to object-relations, which means that you will get not only the reference of the car but the car object.

Your Rest-API return the Java-Object which holds Object-References. That is why your item contains a Car-Object.

If you want to return only the car_id you have to map your output to a new object.

I am junior with REST , but my advice would be : Create CartServices class . Controller only to transfer data to Services. Use @transactional annotations. It is hard to read . I wrote very similar Application : IF you want to check : https://github.com/justassub/ShopProject/tree/master/RESTserver/src/main/java/lt/it/akademija Sorry , it was my first application and not everything was in english. BUT IT IS VERY SIMILAR - only Cart - users.

When you wrote :

@OneToMany(mappedBy = "cart")
private Set<Item> items;

write method :

public void addItem(Item item) {
    this.items.add(item);
    item.setCart(this);
}

and then Cart.addItem(item); And other OF course you need to create getCart/setCart in your items List

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM