James Baker
James Baker

Reputation: 1256

Embedding objects rather than linking in Spring Data JPA

I'm creating a simple web store as part of a larger application, using Spring Boot and Spring Data JPA. I have a number of items (my stock), and an order will consist of a collection of those items (along with shipping information, etc).

It's possible that items in the stock will update - for example, changing the price. I want to be able to do this without the overhead of versioning, etc. However, when I look up past orders I want to get the information that was used at the time.

Is there a way in Spring Data JPA of embedding a copy of the item in my order, rather than linking to the item object?

My classes are below:

ShopItem.java

@Entity
public class ShopItem {
  @Id
  @GeneratedValue
  private Long id;

  private String name;
  private String description;
  private int price;
  private int stock;

  public Long getId() {
    return id;
  }
  public void setId(Long id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }

  public String getDescription() {
    return description;
  }
  public void setDescription(String description) {
    this.description = description;
  }

  public int getPrice() {
    return price;
  }
  public void setPrice(int price) {
    this.price = price;
  }

  public int getStock() {
    return stock;
  }
  public void setStock(int stock) {
    this.stock = stock;
  }
  public void reduceStock(int by){
    this.stock = this.stock - by;
  }
}

ShopOrder.java

@Entity
public class ShopOrder {
  @Id
  @GeneratedValue
  private Long id;

  @ManyToOne
  private Member member;

  private boolean postage;
  @OneToMany
  private List<ShopOrderItem> items;

  public Long getId() {
    return id;
  }
  public void setId(Long id) {
    this.id = id;
  }

  public Member getMember(){
    return member;
  }
  public void setMember(Member member) {
    this.member = member;
  }

  public boolean getPostage() {
    return postage;
  }
  public void setPostage(boolean postage) {
    this.postage = postage;
  }

  public List<ShopOrderItem> getItems() {
    return items;
  }
  public void setItems(List<ShopOrderItem> items) {
    this.items = items;
  }
}

ShopOrderItem.java

@Entity
public class ShopOrderItem {

  @Id
  @GeneratedValue
  private Long id;

  @ManyToOne
  private ShopItem item;
  private int quantity;

  public ShopOrderItem(ShopItem item, int quantity){
    this.item = item;
    this.quantity = quantity;
  }

  public Long getId() {
    return id;
  }
  public void setId(Long id) {
    this.id = id;
  }

  public ShopItem getItem() {
    return item;
  }
  public void setItem(ShopItem item) {
    this.item = item;
  }

  public int getQuantity() {
    return quantity;
  }
  public void setQuantity(int quantity) {
    this.quantity = quantity;
  }

  public int getTotalPrice(){
    return item.getPrice() * quantity;
  }
}

Upvotes: 0

Views: 173

Answers (1)

minioim
minioim

Reputation: 858

Spring Data JPA is only a way to make your life easier when you use an ORM. and a ORM is only a way to make your life easier when you use a Database.

The thing is, if you are using a relational Database, there is no way to do what you want except by cloning datas.

so, one way is to clone your ShopItem entity and store it as a new entry in your database in a dedicated table.

another way may be to use a NoSQL DB which could handle this better.

There is a number of different ways to store a history of orders, but I can't think of anything from Spring data JPA which could do it out of the box.

Upvotes: 1

Related Questions