shalam mohsen
shalam mohsen

Reputation: 5

Spring JPA findAll query to return without nested field from foreign key mapping

I dont know how to ask this question, but hope my explanation help

My issue is getting this result:

[
{
    "product_id": 30001,
    "product_name": "shoe",
    "product_price": 40.5,
    "product_description": "for gym",
    "seller": {
        "seller_id": 20001,
        "seller_name": "cindi",
        "seller_email": "[email protected]",
        "seller_pswd": "abc123",
        "seller_contact": "92212152",
        "seller_wallet": 456
    }
},
{.....

But I want to return like this (direct fetch from mysql ) when i fetch from spring:

enter image description here

Model for product:

@Entity
@Data
@SequenceGenerator(name="seq", initialValue=3000, allocationSize=1)
public class Product {
  
  @Id
  private int product_id;
  private String product_name;
  private BigDecimal product_price;
  private String product_description;

  @ManyToOne
  @JoinColumn(name = "seller_id")
  private Seller seller;

  @JsonIgnore
  @ManyToMany(mappedBy = "products")
  private Set<Cart> cart;
     
}

Model for seller:

@Entity
@Data
@SequenceGenerator(name="seq", initialValue=2000, allocationSize=1)
public class Seller {

  @Id
  private int seller_id;
  private String seller_name;
  private String seller_email;

  @Size(min=5, message = "Password must contain atleast 8 character")
  @NotNull(message = "Password cannot be blank")
  private String seller_pswd;
  private String seller_contact;

  @JsonIgnore
  @OneToMany(mappedBy = "seller")
  private Set<Product> product;
     
}

Is there any way to make it return the same as my actual db? or should i just remove all the mappings in the Model?

and since we are asking about model mapping, (onetoone, manytomany, etc...,) is there any benefit to it for my case - a seller info need to be in the table before adding products, and after that products can be add any time, many times after that.

i dont need to add a seller with many products in 1 go, which to my undersrtanding which is why this mappings are essential IF that is for my case. but for my case, do i really need to do mapping? i feel like removing all mappings and just create relationship thru table creation directly at in the db.

not sure which one

Upvotes: 0

Views: 1351

Answers (2)

shalam mohsen
shalam mohsen

Reputation: 5

I managed to make it fetch as expected.. After trial and error from googling, i just added this to my Product model:

@Entity
@Data
@SequenceGenerator(name = "seq3", initialValue = 3000, allocationSize = 1)
public class Product {

  @Id
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq3")
  private int product_id;
  private String product_name;
  private BigDecimal product_price;
  private String product_description;

  @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "seller_id", scope = Seller.class)
  @JsonIdentityReference(alwaysAsId = true)
  @JsonProperty("seller_id")
  @ManyToOne
  @JoinColumn(name = "seller_id")
  private Seller seller;

  @JsonIgnore
  @ManyToMany(mappedBy = "products")
  private Set<Cart> cart;

}

and this is my result from postman:

[
{
    "product_id": 30001,
    "product_name": "shoe",
    "product_price": 40.5,
    "product_description": "for gym",
    "seller_id": 20001
},
{
    "product_id": 30002,
    "product_name": "bag",
    "product_price": 140.6,
    "product_description": "for travel",
    "seller_id": 20001
},
{
    "product_id": 30003,
    "product_name": "cap",
    "product_price": 20.5,
    "product_description": "protect from the sun",
    "seller_id": 20002
},
{
    "product_id": 30004,
    "product_name": "shirt",
    "product_price": 30.45,
    "product_description": "jalan jalan",
    "seller_id": 20002
}

but another problem comes when i try to add products, respond:

"timestamp": "2021-07-14T17:06:20.247+00:00",
"status": 400,
"error": "Bad Request",
"trace": "org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unresolved forward references for: ; nested exception is com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Unresolved forward references for: \n at [Source: (PushbackInputStream); line: 7, column: 5]Object id [20001] (for `shah.MockAShop.Models.Seller`) at [Source: (PushbackInputStream); line: 6, column: 27].\r\n\tat org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:389)\r\n\tat org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:342)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:185)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:158)\r\n\tat org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:131)\r\n\tat org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)\r\n\tat org.sp

I guess this leaves for another question, another day....

Upvotes: 0

Umesh Sanwal
Umesh Sanwal

Reputation: 777

Yes, you can do that by introducing the below field in Product.java and putting fetch=FetchType.LAZY in @ManyToOne

@Column(name = "seller_id", insertable = false, updatable = false)
private long sellerId;


@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "seller_id" )
private Seller seller;

Upvotes: 0

Related Questions