Viany Manuel
Viany Manuel

Reputation: 55

Why does my repository findAll() method also returns child objects?

I have a Spring project using Spring JPA. I have a table for Brands and Products, and I have mapped them through @ManyToMany like so:

BRAND ENTITY:

@Entity
public class Brand{


@Id
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = 
"brand_seq_gen")
@SequenceGenerator(name = "brand_seq_gen", sequenceName = "ISEQ$$_73370", allocationSize = 1)
@Column(name = "BRAND_ID")
private Long brandId;

@Column(name = "BRAND_NAME")
private String brandName;

@ManyToMany(fetch = FetchType.LAZY, cascade = {
    CascadeType.ALL
})
@JoinTable(
    name = "BRAND_PRODUCT",
    joinColumns = @JoinColumn(name = "BRAND_ID", referencedColumnName = "BRAND_ID"),
    inverseJoinColumns = @JoinColumn(name = "PRODUCT_ID", referencedColumnName = "PRODUCT_ID")
)
private Set<Product> products = new HashSet<>();    

 //CONSTRUCTORS, SETTERS, AND GETTERS
}

PRODUCT ENTITY:

@Entity
public class Product{


@Id
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "prod_seq_gen")
@SequenceGenerator(name = "prod_seq_gen", sequenceName = "ISEQ$$_73373", allocationSize = 1)
@Column(name = "PRODUCT_ID")
private Long productId;

@Column(name = "TYPE_DESCRIPTION")
private String typeDescription;

public Product() {
}

@ManyToMany(mappedBy = "products", fetch = FetchType.LAZY)
private Set<Brand> brands = new HashSet<>();
//Setters, Getters, and Constructors

and for example, I would only want to get the information of Brand only (BRAND_ID and BRAND_NAME) without getting the products, how would I access only the brand's information? Thank you!

--EDIT 1--

I would like to access ALL brands without accessing the products on each brand. Is that possible? Or do I create another class?

--EDIT 2--

Here is a sample query when using BrandRepository.findall()

[ {
 "brandId" : 1,
  "brandName" : "Electrolux",
  "products" : [ {
    "productId" : 4,
    "typeDescription" : "Refrigerator"
  }, {
    "productId" : 3,
    "typeDescription" : "Washing Machine"
  } ]
}, {
  "brandId" : 2,
  "brandName" : "Midea",
  "products" : [ {
    "productId" : 4,
    "typeDescription" : "Refrigerator"
  }, {
    "productId" : 2,
    "typeDescription" : "Air Conditioner"
  }, {
    "productId" : 3,
    "typeDescription" : "Washing Machine"
  } ]
}, {
  "brandId" : 3,
  "brandName" : "Samsung",
  "products" : [ {
    "productId" : 1,
    "typeDescription" : "TV"
  }, {
    "productId" : 4,
    "typeDescription" : "Refrigerator"
  } ]
}, {
  "brandId" : 4,
  "brandName" : "LG",
  "products" : [ {
    "productId" : 1,
    "typeDescription" : "TV"
  } ]
} ]

What I want should only be the columns brandId and brandName without the products resulting from @ManyToMany relationship.

--Edit 4-- I found out through logging that the database is being queried two times to retrieve both tables which is why I think it might be better to just use @Query and a projection.

Upvotes: 1

Views: 1027

Answers (3)

Aleksander Nuszel
Aleksander Nuszel

Reputation: 330

Make sure to have spring.jpa.open-in-view=false in your application.properties file. If you have it set to true you will end up querying database when you call get method on your entity.

Upvotes: 2

MartinBG
MartinBG

Reputation: 1648

The simplest way to fetch just some entity properties is to use projections

Back to your example, you could have a projection interface defined like that:

interface BrandNameAndId {
  Long getId();
  String getBrandName();
}

And a method like this in your Brand's repository:

List<BrandNameAndId > findAllProjectedBy();

Upvotes: 1

chirag soni
chirag soni

Reputation: 1026

Use hibernate lazy loading that will fetch only brands, not the child items(products).

Please have a look at this to understand what the lazy loading means.

Upvotes: 2

Related Questions