【发布时间】:2016-07-01 15:24:31
【问题描述】:
我有一个检索用户的控制器方法,然后我映射了他们的 UserConfig,然后使用该 UserConfig 我检索 MainBrands(UserConfiguration 的惰性集合)。
让我澄清一下:
用户实体:
@Entity
@Table(name = "app_user")
public class User extends BaseEntity {
private UserConfig userConfig;
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
public UserConfig getUserConfig() {
return userConfig;
}
//more props..
}
用户配置实体:
@Entity
@Table(name = "user_config")
public class UserConfig extends BaseEntity {
private Set<MainBrand> mainBrands;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(...)
public Set<MainBrand> getMainBrands() {
return mainBrands;
}
//more props..
}
还有我的用户服务:
public interface UserService {
public User getById(Long id);
}
所以我的问题是关于事务注释的“最佳实践”。我不止一次读过,将@Transactional 放在控制器级别,这是不好的做法。但在这种情况下,我想在 Controller 做:
@RequestMapping(method = RequestMethod.GET, value = "/")
public ModelAndView getMainPage(Long userId) {
ModelAndView = new ModelAndView("/home");
//do stuff
User user = userService.getById(userId);
//some stuff with user
modelAndView.addObject("username", user.getUsername());
//...
List<String> brandsNames = new ArrayList<>();
for(MainBrand mainBrand : user.getUserConfig().getMainBrands()){
brandsNames.add(mainBrand.getName());
}
}
如果不将 @Transactional 注释放在控制器级别,那将失败,因为 LazyInitializationException。
所以,这就是我想出来的选择:
1) 与用户一起调用“UserConfigService”(现在尚未创建),例如 userConfigService.getUserConfigByUserId(userId):这让我认为,如果我已经在 User 处进行了绑定类,为什么我会再次调用它?我只是为这种方法创建一个新服务。
2) 将@Transactional 注释放在控制器级别:这对我来说是另一个问题,但在这篇文章中并不关心。
3) 在 UserService 调用 getUserConfig() 和 getUserConfig().getMainBrands() 以便初始化集合:不喜欢,因为每当我使用 getById 时,它甚至会初始化集合如果我不需要它。
那么对于这种情况,什么是好的做法?互联网上总是有完美漂亮的例子,但是当我们开始给项目一些业务逻辑时,很难有一个干净的代码。
谢谢,对不起我的英语。
【问题讨论】:
标签: java spring hibernate controller transactional