我使用的是Spring数据jpa& hibernate用于数据访问以及Spring启动。默认情况下,所有存储库bean都是单例。我想将所有存储库的范围定义为Prototype
。我怎样才能做到这一点?
@Repository
public interface CustomerRepository extends CrudRepository<Customer, Long> {
List<Customer> findByLastName(String lastName);
}
修改1
问题与2个不同事务中共享的域对象有关,这导致我的代码失败。我认为它正在发生,因为存储库bean是单例。这就是我问这个问题的原因。以下是该场景的详细说明。
我有2个实体User
和UserSkill
。 User
与UserSkills
保持1 * *关系,UserSkill
关系启用了延迟加载。
在UserAggregationService
中,我首先拨打电话,以ID 123
来获取个人用户技能,该ID属于身份1
的用户。
public class UserAggregationService {
public List<Object> getAggregatedResults() {
resultList.add(userSkillService.getUserSkill(123));
//Throws Null Pointer Exception. See below for more details.
resultList.add(userService.get(1));
}
}
UserSkillService方法的实现类似于
@Override
public UserSkillDTO getUserSkill(String id) {
UserSkill userSkill = userSkillService.get(id);
//Skills set to null avoid recursive DTO mapping. Dozer mapper is used
//for mapping.
userSkill.getUser().setSkills(null);
UserSkillDTO result = mapper.map(userSkill, UserSkillDTO.class);
return result;
}
在用户聚合服务的调用中,我调用UserService来获取userDetails。 UserService代码看起来像
@Override
public UserDTO getById(String id) {
User user = userService.getByGuid(id);
List<UserSkillDTO> userSkillList = Lists.newArrayList();
//user.getSkills throws null pointer exception.
for (UserSkill uSkill : user.getSkills()) {
//Code emitted
}
....
//code removed for conciseness
return userDTO;
}
UserSkillService方法实现
public class UserSkillService {
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public UserSkill get(String guid) throws PostNotFoundException {
UserSkill skill = userSkillRepository.findByGuid(guid);
if (skill == null) {
throw new SkillNotFoundException(guid);
}
return skill;
}
}
UserService方法实现:
public class UserService {
@Override
@Transactional(readOnly = true)
public User getByGuid(String guid) throws UserNotFoundException {
User user = userRepo.findByGuid(guid);
if (user == null) {
throw new UserNotFoundException(guid);
}
return user;
}
}
Spring boot auto配置用于实例化实体管理器工厂和事务管理器。在配置文件中,spring.jpa。*键用于连接数据库。
如果我评论下面的代码行,那么我没有得到异常。我无法理解为什么域对象中的更改正在影响另一个事务中的对象提取。
userSkill.getUser().setSkills(null);
请建议如果我错过了什么。