In my application in the controller layer, I can get the user in 2 ways via the JpaRepository (getOne method) and through the hibernet session (getUserByKey method)
Controller layer:

@RestController @RequestMapping("desk") public class MainController { final UserService userService; @Autowired public MainController(UserService userService) { this.userService = userService; } @GetMapping("{id}") public User getUser(@PathVariable long id) { // User user = userService.getOne(id); //через JpaRepository User user = userService.getUserByKey(id); //через сессию hibernet return user; } } 

I have a user with two machines in the database (one-to-many connection) Layer model: User table

 @Entity @Table(name = "user") @ToString(of = {"id", "test"}) @EqualsAndHashCode(of = {"id"}) public class User { public User() { } @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; private String name; private String address; @OneToMany(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY, targetEntity = Car.class) @JoinTable(name = "car", joinColumns = @JoinColumn(name = "ownerId", referencedColumnName = "id")) private List<Car> childIds; 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 getAddress() { return address; } public void setAddress(String address) { this.address = address; } public List<Car> getChildIds() { return childIds; } public void setChildIds(List<Car> childIds) { this.childIds = childIds; } } 

Car table:

 @Entity @Table(name = "car") @ToString(of = {"id", "test"}) @EqualsAndHashCode(of = {"id"}) public class Car { public Car() { } @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; private long ownerId; private String model; @ManyToOne(cascade = {CascadeType.ALL}, fetch = FetchType.LAZY, targetEntity = User.class) @JoinTable(name = "user", joinColumns = @JoinColumn(name = "id", referencedColumnName = "id")) private List<Long> parentIds; public long getId() { return id; } public void setId(long id) { this.id = id; } public long getOwnerId() { return ownerId; } public void setOwnerId(long ownerId) { this.ownerId = ownerId; } public String getModel() { return model; } public void setModel(String model) { this.model = model; } public List<Long> getParentIds() { return parentIds; } public void setParentIds(List<Long> parentIds) { this.parentIds = parentIds; } } 

Service layer:

 @Service @Transactional public class UserServiceImple implements UserService { final UserRepo userRepo; final DAO userDAO; @Autowired public UserServiceImple(UserRepo userRepo, DAO userDAO) { this.userRepo = userRepo; this.userDAO = userDAO; } public User getOne(long id) { return userRepo.getOne(id); //через JpaRepository } @Override public User getUserByKey(long id) { return userDAO.getUserFromBd(id); //через сессию hibernet } } 

JPA repository:

 @Repository public interface UserRepo extends JpaRepository<User, Long> { } 

DAO Layer:

 @Repository public class DAO implements GenericDao<User> { private SessionFactory hibernateFactory; @Autowired public DAO(EntityManagerFactory factory) { if (factory.unwrap(SessionFactory.class) == null) { throw new NullPointerException("factory is not a hibernate factory"); } this.hibernateFactory = factory.unwrap(SessionFactory.class); } @Override public User getUserFromBd(long user_id) { Object query = hibernateFactory.openSession().createQuery("FROM User WHERE id =:user_id") .setParameter("user_id", user_id) .uniqueResult(); return (User) query; } } 

Questions:

1) Why when I use hibernet session (getUserByKey method) to get a user, I see an object in debug in the controller, even if fetch = FetchType.LAZY on all models?

2) Why when I use JpaRepository (getOne method) to get a user, in debug in the controller I see a proxy object, even if fetch = FetchType.EAGER on all models?

3) How to get an object using JpaRepository?

    1 answer 1

    If you read the API documentation on JpaRepository , then it says that the getOne() method returns a reference to the entity:

    Returns a reference to the entity with the identifier.

    That is, inside this method, EntityManager.getReference() instead of EntityManager.find() or its equivalent in the Hibernate API Session.load() . In order to get the entity itself, and not the link , you need to refer to the entity data, for example user.getName() , in the current transaction (otherwise the entity will not be loaded).

    What is it for? You have a User entity that stores a list of Car s. You can add a new car to the user (let's say with id = 1234 ) in 2 ways:


     Car car = entityManager.find(Car.class, 1234L); user.getChildIds().add(car); 

     Car car = entityManager.getReference(Car.class, 1234L); user.getChildIds().add(car); 

    The second method will be faster since the car entity will be loaded without data .

    • Is it possible to get a proxy object using a hibernet session? - harly
    • @harly session.load() returns a proxy (if entities with this identifier are no longer in Persistence Context-е ) - not a Programmer