mil*_*bos 19 spring hibernate jpa repository
有这样的课程:
用户.java:
@Entity
@Setter
@Getter
@NoArgsConstructor
public class User {
@Id
private int id;
private String username;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Address address;
public User(String username) {
this.username = username;
}
}
Run Code Online (Sandbox Code Playgroud)
地址.java:
@Entity
@Data
public class Address {
@Id
private int id;
private String country;
@OneToOne
private User user;
}
Run Code Online (Sandbox Code Playgroud)
用户存储库.java:
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
}
Run Code Online (Sandbox Code Playgroud)
演示应用程序.java:
@Bean
public CommandLineRunner loadData(UserRepository userRepo){
return new CommandLineRunner() {
@Override
public void run(String... args) throws Exception {
User u = new User("motherfucker");
Address a = new Address();
a.setCountry("CZ");
u.setAddress(a);
a.setUser(u);
userRepo.save(u);
//User newUser = userRepo.getById(0);
User newUser = userRepo.findById(0).orElse(null);
System.out.println(newUser.getUsername());
}
};
}
Run Code Online (Sandbox Code Playgroud)
现在工作没有问题(在from which extendsfindById(int: id)
中定义)。然而,(在 中定义)甚至给出了映射中指定的属性。在文档中它说CrudRepository
JpaRepository
getById(int :id)
JpaRepository
LazyInitializationException
fetch = Fetch.EAGER
返回对具有给定标识符的实体的引用。根据 JPA 持久性提供程序的实现方式,这很可能始终返回一个实例并在第一次访问时抛出 EntityNotFoundException。其中一些会立即拒绝无效标识符。
EntityNotFoundException
但是LazyInitializationException
从这个描述来看,对我来说,如果这个方法总是抛出异常,那么它就没用。为什么会有这个方法存在?
在休眠中获取数据的正确方法(方法)是什么?
小智 15
通常我们可以使用 findById 或 getById 。使用其中任何一个都没有问题。
但如果我们想了解更具体的差异,这些差异如下:
- getById:仅当我们确定从数据库中获取我们请求的实体时才使用此方法。如果我们没有得到任何实体,则会出现异常。这就像一个孩子想要什么就得到什么,但如果没有得到他想要的东西,他就会开始尖叫。
- findById:如果我们不确定数据库中是否存在所请求的实体,则使用此方法。因此,即使该实体不存在于数据库中,它也会返回 null 并且不会引发任何异常。
LazyInitializationException
正是因为你设置了fetch = Fetch.EAGER
。getById()
返回一个延迟获取的实体,从而返回异常。getById()
。但说实话我也不明白。强调另一个细节也很重要:方法内部findById()
使用方法并使用方法。结果,返回实际对象并返回实体的引用。EntityManager
find(Class<T> entityClass, Object primaryKey, LockModeType lockMode, Map<String,Object> properties))
getById()
EntityManager
getReference(Class<T> entityClass, Object primaryKey)
findById()
getById
参考文档:
getById -> 返回实际实体的引用代理。其中仅设置了 id(因为您已经通过了它)。该对象的 getter 和 setter 可以在同一个 @Transaction 中调用。但是,一旦退出事务,代理将返回 LazyInitializationException。
如果你查看 getReference java 文档。我相信这一切都清楚了。因此,如果您调用 getById,hibernate不会访问数据库。
获取一个实例,其状态可以被延迟获取。如果数据库中不存在请求的实例,则首次访问实例状态时会抛出EntityNotFoundException。(当调用 getReference 时,允许持久性提供程序运行时抛出 EntityNotFoundException。)应用程序不应期望实例状态在分离时可用,除非应用程序在实体管理器打开时访问了实例状态。
另一方面,findById直接命中DB并执行select查询。
归档时间: |
|
查看次数: |
29531 次 |
最近记录: |