public class VacancyEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Integer id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "job_category_id", nullable = false)
JobCategoryEntity jobCategory;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "company_id", nullable = false)
CompanyEntity company;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "employer_created_by", nullable = false)
EmployerProfileEntity employerCreatedBy;
@Column(nullable = false)
String title;
.... }
public class VacancyDto {
Integer id;
String title;
CompanyDto company;
EmployerProfileDto employerCreatedBy;
JobCategoryDto jobCategory;
...}
因此,我在VacancyRepository
中有两个方法FindByIdWithCompanyandCity
和FindByIdWithJobandCityAndEmploymente
,只执行一个SQL请求。
和我的VacancyService
中的两个@Transaction
方法:FindWithCompanyandCity
和FindWithCompanyandCityandEmployment
。
最佳实践是从服务层返回Dto,因此我们需要将实体解析为服务中的Dto。
我真的不想把整个映射留在@transactional
(session),因为如果我在实体中添加一些字段,那么Mapstruct只会触发N+1个问题。
我想出的最好方法是将每个内部实体包含到方法中,并手动检查Mapstruct是否添加了一些新方法。(它比检查名字更快)例如:
@Mapping(target = "id", source = "entity.id")
@Mapping(target = "description", source = "entity.description")
@Mapping(target = "jobCategory", source = "jobCategoryDto")
@Mapping(target = "employerCreatedBy", source = "employerProfileDto")
@Mapping(target = "city", source = "cityDto")
@Mapping(target = "company", ignore = true)
VacancyDto toDto(VacancyEntity entity,
JobCategoryDto jobCategoryDto,
EmployerProfileDto employerProfileDto,
CityDto cityDto);
....
但这并不能解决真正的问题。映射时仍然存在会话,因此会导致N+1问题。
我知道在这两种情况下我都会得到LazyInitializationException
,但在我看来,它比不可预测的select更健壮、更可伸缩。
如何以优雅的方式在服务层但在Hibernate会话之外执行从实体到DTO的映射?
你没有问一个问题,但似乎这个问题应该是:
如何以优雅的方式在服务层但在Hibernate会话之外执行从实体到DTO的映射。
为此,我建议使用TransactionTemplate
。用法如下所示:
@Autowired
VacancyRepository repo;
@Autowired
TransactionTemplate tx;
void someMethod(String company, String city){
VacancyEntity vac = tx.execute(__ -> repo.findWithCompanyAndCity(company, city));
return mappToDto(vac);
}
我对这些技术是新的,所以提前道歉。 我在我的应用程序中使用了springboot、Spring JPA、hibernate和mapstruct。
我在学习冬眠时遇到了一个问题。我写了UnitTest和那里我尝试添加对象到DB。所有选择都正常工作,但插入不正常。 我也尝试过这样的东西 它引发了一个异常,事务没有成功启动,但它添加了用户 这里有一个例外 组织。springframework。交易TransactionSystemException:无法回滚Hibernate事务;嵌套的异常是org。冬眠TransactionException:
我指的是https://developer.jboss.org/wiki/SessionsAndTransactions,目前正试图了解与JTA的划界问题。它声明在使用getCurrentSession()的特定事务中,总是给出相同的当前会话。是不是意味着: < li >如果另一个用户在另一个线程中执行同一段代码(通过查找获取一个事务,然后使用getCurrentSession()并关闭该事务),
我有两个方法,它们都被注释为@Transactional。 我知道这两种方法将在两个不同的事务中执行。 但是这两个方法是在一个Hibernate会话中执行吗? spring事务管理器将会话保持到http请求结束。 我知道事务管理器可能会在它的 aop 代理中执行类似操作: 我只是找不到代码,如果我能在某处找到代码,我可以自己回答这个问题。
我找了很多解决办法。谢了。
问题内容: 我是Spring框架的初学者。 在我的情况下,会话可以通过以下方式过期 ->成功注销(显式注销) ->会话超时(隐式注销) 每当某些用户登录时,我都会在数据库中执行DML(记录插入),并且每当用户会话超时(隐式注销)时,我都希望在数据库中执行DML(记录删除)。 我的问题是,春季会议期间有什么办法告诉我们。因此,我可以在会话到期前执行自定义事件。 提前致谢 问题答案: 是的,您可以使用