Getting same value on Fetctype Lazy and Eager

Ashwin Karki :

I am new to Jpa and I added spring boot jpa in my spring boot for One to One mappings. So,

package com.jpa.onetoone.onetoonejpa.model;

import org.hibernate.annotations.GeneratorType;

import javax.persistence.*;

@Entity
public class User {

   @Id
   @GeneratedValue
   private Long id;

   private String username;

   private String password;

   @OneToOne(cascade=CascadeType.ALL,mappedBy = "user",fetch = FetchType.LAZY)
   private Address address;

    public User(String username, String password) {

        this.username = username;
        this.password = password;
    }

    public Long getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    public User() {
    }
}

Address.java file is

package com.jpa.onetoone.onetoonejpa.model;

import com.fasterxml.jackson.annotation.JsonIgnore;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;

@Entity
public class Address {

    @Id
    @GeneratedValue
    private Long id;

    private String homeAddress;

    private int homeNumber;

    @OneToOne
    @JsonIgnore
    private User user;


    public Address(String homeAddress, int homeNumber) {
        this.homeAddress = homeAddress;
        this.homeNumber = homeNumber;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Long getId() {
        return id;
    }

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

    public String getHomeAddress() {
        return homeAddress;
    }

    public void setHomeAddress(String homeAddress) {
        this.homeAddress = homeAddress;
    }

    public int getHomeNumber() {
        return homeNumber;
    }

    public void setHomeNumber(int homeNumber) {
        this.homeNumber = homeNumber;
    }

    public Address() {
    }
}

I have added one to one relationship between User and Address.I have inserted the data in database and want to acquire data through RestController.So,I am just testing my application using FetchType.Lazy and FetchType.Eager in User class but I am getting the same Json.There is no change in JSOn with the FetchType.

When I hit the URL :http://localhost:8080/users in both fetchtype.lazy and fetchtype.eager i am getting the same JSON as the address field needs to be eradicated as I use fetchtype.lazy in Address field.

 @OneToOne(cascade=CascadeType.ALL,mappedBy = "user",fetch = FetchType.LAZY)
   private Address address;

The JSON i am getting in both case is:

[  
   {  
      "id":3,
      "username":"ashwin",
      "password":"karki",
      "address":{  
         "id":4,
         "homeAddress":"kapan",
         "homeNumber":71444
      }
   }
]

Another question I want to ask is,when I try to access http://localhost:8080/address ,I also want User object associated with address.The loop went to infinite and I added JsonIgnore,then the Json is printed like below.Is there any way, we can access both user from address and address from user when hitting these two URL?

[  
   {  
      "id":4,
      "homeAddress":"kapan",
      "homeNumber":71444
   }
]

DefaultController.java

package com.jpa.onetoone.onetoonejpa.controller;


import com.jpa.onetoone.onetoonejpa.model.Address;
import com.jpa.onetoone.onetoonejpa.model.User;
import com.jpa.onetoone.onetoonejpa.repository.AddressRepository;
import com.jpa.onetoone.onetoonejpa.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class DefaultController {


    @Autowired
    private UserRepository userRepository;

    @Autowired
    private AddressRepository addressRepository;


    @GetMapping(value = "/users")
    public List<User> getUsers() {

        List<User> users = userRepository.findAll();
       return users;
    }

    @GetMapping(value = "/address")
    public List<Address> getAddress() {

        List<Address> address = addressRepository.findAll();
        return address;
    }

}
ilinykhma :

There is no change in JSON with the FetchType - and should not. The fetch type is a strategy of loading data from a database.

With EAGER user and address loads at the same time, with one SQL call:

@GetMapping(value = "/users")
public List<User> getUsers() {

   List<User> users = userRepository.findAll(); // users and addresses was loaded
   return users;
}

With LAZY, address will not be loaded while you don't read them. But, when you return users from a controller, JSON mapper read address property, so it will be loaded with one SQL call per user:

@GetMapping(value = "/users")
public List<User> getUsers() {

   List<User> users = userRepository.findAll(); // users was loaded
   return users; // addresses was loaded for each user one by one
}

And the second question. There are many ways. See JsonView, for example.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=126764&siteId=1