lia*_* xu 2 java spring hibernate jpa
我基于springboot创建了一个用户管理服务。
该用户将有一个列表附件,这样用户和依恋的关系是一对多。
我在这里忽略了插入逻辑,因为我的问题是关于延迟加载以及何时打开和关闭entitymanager。以下是实体,控制器,服务,Dao,存储库相关的代码。
实体
@Entity
@Table(name="User")
public class UserInfoEntity {
private long id;
private String mail;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "userInfoEntity", cascade = CascadeType.ALL)
private List<UserAttachmentEntity> attachmentList = new ArrayList<>();
}
@Entity
@Table(name = "ATTACHMENT")
public class UserAttachmentEntity {
private long id;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="userRequestId")
private UserInfoEntity userInfoEntity;
}
Run Code Online (Sandbox Code Playgroud)
服务
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
@Transactional
public void save(UserInfoEntity userInfoEntity) throws RestException {
userDao.save(userInfoEntity);
}
@Override
// I did set @Transactional here
public UserInfoEntity findByMail(String mail) {
UserInfoEntity userInfoEntity = userDao.findByMail(mail);
return userInfoEntity;
}
}
Run Code Online (Sandbox Code Playgroud)
道
@Service
public class UserDaoImpl implements UserDao {
@PersistenceContext
private EntityManager entityManager;
@Autowired
private UserInfoEntityRepository userInfoRepository;
@Override
public UserInfoEntity findByMail(String mail) {
return userInfoRepository.findFirstByMailOrderByIdDesc(mail);
}
}
Run Code Online (Sandbox Code Playgroud)
资料库
@Repository
public interface UserInfoEntityRepository extends JpaRepository<UserInfoEntity, Integer> {
UserInfoEntity findFirstByMailOrderByIdDesc(String mail);
}
Run Code Online (Sandbox Code Playgroud)
控制者
@Controller
@RequestMapping(value = "/user")
public class UserController {
@RequestMapping(value = "load", method = RequestMethod.POST)
@ResponseBody
public UserInfoEntity load(UserInfoEntity userInfoEntityInput, HttpServletRequest request) throws Exception {
UserInfoEntity userInfoEntity = userService.findByMail(userInfoEntityInput.getMail());
System.out.println(userInfoEntity.getAttachmentList());
return userInfoEntity;
}
}
Run Code Online (Sandbox Code Playgroud)
在控制器中测试加载方法后,我发现即使我将
@OneToMany(取= FetchType.LAZY,...)在 UserInfoEntity。
我仍然可以在controller中调用userInfoEntity.getAttachmentList()。(我可以看到在其中打印了来自附件查询的select *)
lazyinitializationexception-in-spring-data-jpa后的回答说,您需要在事务内部时获取懒惰数据。
但是我没有在服务中的findByMail方法中设置@Transaction。
我记得几天前我也遇到了这个例外。但是现在我可以在控制器中成功加载惰性数据了。
我主要有以下问题。
提前致谢。我在公司中写了这个问题,不允许在公司中将任何代码推送到github。如果可以的话,我认为这对您会更方便,因为带有h2数据库的spring boot项目在本地很容易设置。
如果您查阅附录A.常见的应用程序属性,默认情况下会发现Spring boot定义
spring.jpa.open-in-view=true
Run Code Online (Sandbox Code Playgroud)
那实际上是登记OpenEntityManagerInViewInterceptor。将JPA绑定EntityManager到线程以完成请求的整个处理。这实际上导致混乱,请参阅社区报告的此问题。
基本上,EntityManager打开一个事务,在该事务中@Transaction声明了注释,或者在您的情况下,注释由OpenEntityManagerViewInterceptor每个请求打开,并且在做出响应之前保持打开状态。
没有。它不是线程安全的,但是EntityManagerFactory是。并EntityManager从获得EntityManagerFatory。因此,EntityManager价格便宜,并且可以用于单个工作单元。EntityManagerFactory通常在应用程序初始化时创建An ,然后在应用程序端将其关闭。有关在Java SE环境中获取EntityManager的详细信息,请参见Hibernate文档。
不会。EntityManager是一个接口,在您自动装配时注入到spring bean中的不是实体管理器本身,而是上下文感知的代理,它将在运行时委派给具体的实体管理器。通常,用于代理的具体类是SharedEntityManagerInvocationHandler
有关整个JPA事务如何进行的更多详细说明。我建议阅读这本Spring @Transactional如何真正起作用?
| 归档时间: |
|
| 查看次数: |
74 次 |
| 最近记录: |