Почему пользователь возвращается из базы данных как объект через сеанс hibernet и через JpaRepository как объект прокси? - PullRequest
0 голосов
/ 21 марта 2019

У меня есть следующее веб-приложение на Spring Boot.На уровне контроллера я могу получить пользователя двумя способами через JpaRepository (метод getOne) и через сеанс Hibernate (метод getUserByKey). Уровень контроллера:

@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);     //through the JpaRepository
       User user = userService.getUserByKey(id);  //through the hibernate session 
       return user;
    }
}

У меня есть пользователь с двумя машинами вбаза данных (один ко многим)

Модель слоя:

Таблица пользователей:

@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;
    }
}

Таблица машин:

@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
@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); //through the JpaRepository
    }

    @Override
    public User getUserByKey(long id) {
        return userDAO.getUserFromBd(id); //through the hibernate session 
    }
}

Репозиторий JPA:

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

}

Уровень DAO:

@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;
    }
}

Вопросы:

1) Почему, когда я использую сеанс Hibernet (метод getUserByKey), чтобы получить пользователя, я вижу объект в отладке в контроллере, даже если fetch = FetchType.LAZY на всех моделях?

2) Почему, когда я использую JpaRepository (метод getOne), чтобы получить пользователя, в отладке в контроллере я вижу прокси-объект, даже если fetch = FetchType.EAGER на всех моделях?

3) Как получить объект с помощью JpaRepository?

4) Как я могупереключить тип выборки (EAGER) на FetchType.LAZY, используя сеанс hibernet?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...