Hi,
When I use @ManyToOne(optional = false,fetch = FetchType.LAZY) in a property and it seems like lazy loading not work. I use 'spring-boot-starter-data-jpa' . My code as follows
Person.java
public class Person implements Serializable {
@Id
private final String id = UUID.randomUUID().toString();
@Column
private String name;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "person", orphanRemoval = false, fetch = FetchType.LAZY)
@JsonManagedReference("bankCards")
@Valid
@Size(min = 1)
private List<BankCard> bankCards = new ArrayList<>();
}
BankCard.java
@Data
@Entity
@Table(name = "lazy_test_bank_card")
public class BankCard implements Serializable {
@Id
private final String id = UUID.randomUUID().toString();
@Column
private String bankName;
@ManyToOne(optional = false,fetch = FetchType.LAZY)
@JoinColumn(name = "person_id")
@JsonBackReference("bankCards")
private Person person;
}
BankCardRepository.java
import com.omg.lazyLoadingTest.model.BankCard;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@Repository
@Transactional
public interface BankCardRepository extends JpaRepository<BankCard, String>,
JpaSpecificationExecutor<BankCard> {
}
TestController.java
import com.omg.lazyLoadingTest.model.BankCard;
import com.omg.lazyLoadingTest.model.Person;
import com.omg.lazyLoadingTest.repository.BankCardRepository;
import com.omg.lazyLoadingTest.repository.PersonRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/test")
public class TestController {
@Autowired
private PersonRepository personRepository;
@Autowired
private BankCardRepository bankCardRepository;
@GetMapping(path = "/person1/{id}")
public Person person1(@PathVariable String id) {
Person person = personRepository.findOne(id);
//At this case ,@OneToMany lazy loading worked, it will not load the 'bankCards'
return person;
}
@GetMapping(path = "/bankCard/{id}")
public BankCard bankCard(@PathVariable String id) {
BankCard bankCard = bankCardRepository.findOne(id);
//However at this case, @ManyToOne lazy loading not worked, it will load the 'person' although I configured FetchType.LAZY
return bankCard;
}
}
When I test it , the 'bankCards' property in Person.java can use lazy loading but the 'person' property in BankCard.java lazy loading not worked.
When call bankCardRepository.findOne(id); The sql in the console are:
Hibernate: select bankcard0_.id as id1_0_0_, bankcard0_.bank_name as bank_nam2_0_0_, bankcard0_.person_id as person_i3_0_0_ from lazy_test_bank_card bankcard0_ where bankcard0_.id=?
Hibernate: select person0_.id as id1_2_0_, person0_.name as name2_2_0_ from lazy_test_person person0_ where person0_.id=?