我在Spring Boot上有以下Web应用程序。在控制器层,我可以通过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)如何使用hibernet会话将获取类型(EAGER)切换为FetchType.LAZY?