Java Hibernate即使使用@Transactional,也无法在实体服务中延迟初始化角色no会话的集合
我有一个hibernate项目,它连接到两个数据源,并有一个基本dao。我还使用基本dao为数据源派生通用dao 我有一个获取连接关系的服务,当实体具有一对多关系时,我会遇到以下错误。我陷入了无法获得一对多关系对象的困境 我使用ApacheCommonsBeanutils来复制属性,希望它能够进行深度复制,但它也不起作用。我的想法快用完了 我读到我可以选择在视图中使用OpenSession,但我不确定如何进行 错误 我有以下图层和文件 控制器层Java Hibernate即使使用@Transactional,也无法在实体服务中延迟初始化角色no会话的集合,java,spring,hibernate,annotations,hibernate-onetomany,Java,Spring,Hibernate,Annotations,Hibernate Onetomany,我有一个hibernate项目,它连接到两个数据源,并有一个基本dao。我还使用基本dao为数据源派生通用dao 我有一个获取连接关系的服务,当实体具有一对多关系时,我会遇到以下错误。我陷入了无法获得一对多关系对象的困境 我使用ApacheCommonsBeanutils来复制属性,希望它能够进行深度复制,但它也不起作用。我的想法快用完了 我读到我可以选择在视图中使用OpenSession,但我不确定如何进行 错误 我有以下图层和文件 控制器层 @ApiOperation(value =
@ApiOperation(value = "read", nickname = "getByID")
@RequestMapping(value="/read", method = RequestMethod.GET)
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "User's id", required = true, dataType = "int", paramType = "query")
})
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Success", response = User.class),
@ApiResponse(code = 500, message = "Failure")})
@ResponseBody
public UserProxy getByID(long id) {
UserProxy user;
try {
user = userService.fetchUserById(id);
}
catch(Exception ex) {
ex.printStackTrace();
return null;
}
return user;
}
服务层
用户服务
@Service
@Transactional("fuseTransactionManager")
public class UserServiceImpl extends BaseFuseServiceImpl<User> implements UserService {
@Autowired
UserDao userDao;
@Override
protected UserDao getDao() {
return userDao;
}
@Override
public UserProxy fetchUserById(long id) {
try {
/***** ERROR HAPPENS HERE. THE USER OBJECT IS NOT ABLE TO GET THE ONE TO MANY OBJECTS even though I have @Transactional *****/
User user = userDao.fetchEntityById(User.class, id);
UserProxy userProxy = new UserProxy();
BeanUtils.copyProperties(userProxy, user);
return userProxy;
} catch(Exception ex) {
ex.printStackTrace();
return null;
}
}
.....
@服务
@事务性(“fuseTransactionManager”)
公共类UserServiceImpl扩展BaseFuseServiceImpl实现UserService{
@自动连线
UserDao UserDao;
@凌驾
受保护的UserDao getDao(){
返回userDao;
}
@凌驾
公共UserProxy fetchUserById(长id){
试一试{
/*****此处发生错误。即使我有@Transactional,用户对象也无法获取一对多对象*****/
User User=userDao.fetchEntityById(User.class,id);
UserProxy UserProxy=新的UserProxy();
copyProperties(userProxy,user);
返回userProxy;
}捕获(例外情况除外){
例如printStackTrace();
返回null;
}
}
.....
通用引信服务
@Service
public class BaseFuseServiceImpl<T extends Serializable> extends BaseServiceImpl<T> implements BaseFuseService<T> {
@Autowired
BaseFuseDao<T> baseFuseDao;
@Override
protected BaseFuseDao<T> getDao() {
return baseFuseDao;
}
}
@服务
公共类BaseFuseServiceImpl扩展BaseFuseServiceImpl实现BaseFuseService{
@自动连线
BaseFuseDao BaseFuseDao;
@凌驾
受保护的BaseFuseDao getDao(){
返回baseFuseDao;
}
}
特定服务实现的非常通用的服务
@Service
@Transactional("baseTransactionManager")
public abstract class BaseServiceImpl<T extends Serializable> implements BaseService<T> {
protected abstract BaseDao<T> getDao();
@Override
public T fetchEntityById(Class<T> entityClass, long id) {
return getDao().fetchEntityById(entityClass, id);
}
@服务
@事务(“baseTransactionManager”)
公共抽象类BaseServiceImpl实现BaseService{
受保护的抽象BaseDao getDao();
@凌驾
公共T fetchEntityById(类entityClass,长id){
返回getDao().fetchEntityById(entityClass,id);
}
用户实体。还有一个对应的代理对象,除了没有@Entity@Column注释外,几乎完全相同
@Entity
@Table(name="USER")
//@AttributeOverride(name = "ID", column = @Column(name = "USER_ID", nullable = false))
public class User extends BaseEntity {
//public class User implements Serializable {
/**
*
*/
private static final long serialVersionUID = 5236507646361562577L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "USER_ID")
private long id;
@OneToMany(cascade=CascadeType.ALL)
@JoinTable(name="USER_OPERATIONALUNIT",
joinColumns = {@JoinColumn(name="USER_ID")},
inverseJoinColumns = {@JoinColumn(name="OPERATIONALUNIT_ID")}
)
private Set<OperationalUnit> operationalUnit;
.... getters and setters
@实体
@表(name=“USER”)
//@AttributeOverride(name=“ID”,column=@column(name=“USER\u ID”,nullable=false))
公共类用户扩展BaseEntity{
//公共类用户实现可序列化{
/**
*
*/
私有静态最终长serialVersionUID=5236507646361562577L;
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
@列(name=“USER\u ID”)
私人长id;
@OneToMany(级联=级联类型.ALL)
@JoinTable(name=“USER\u操作单元”,
joinColumns={@JoinColumn(name=“USER_ID”)},
inverseJoinColumns={@JoinColumn(name=“OPERATIONALUNIT\u ID”)}
)
专用装置;
…接球手和接球手
为什么要在类内创建所有方法@Transactional
。您可以根据需要随时使用@Transactional
。要获得最佳实践,请在方法上使用@Transactional
因此,在您的案例中有两种解决方案:
1.通过急切地吸引孩子:
您需要急切地通过fetchType传递注释,即
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
2.通过使用@Transactional:
在这里,您需要在当前事务中初始化您的集合,即
public UserProxy fetchUserById(long id) {
try {
User user = userDao.fetchEntityById(User.class, id);
// Here you need to initialize collection using getter method after retrieving object
user.getOperationalUnit().size();
//Now you will get childs with your parent entity
UserProxy userProxy = new UserProxy();
BeanUtils.copyProperties(userProxy, user);
return userProxy;
} catch(Exception ex) {
ex.printStackTrace();
return null;
}
}
有关
@Transactional
为什么要在类内创建所有方法的更多详细信息。您可以在需要时使用@Transactional
。有关最佳实践,请在方法上使用@Transactional
因此,在您的案例中有两种解决方案:
1.通过急切地吸引孩子:
您需要急切地通过fetchType传递注释,即
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
2.通过使用@Transactional:
在这里,您需要在当前事务中初始化您的集合,即
public UserProxy fetchUserById(long id) {
try {
User user = userDao.fetchEntityById(User.class, id);
// Here you need to initialize collection using getter method after retrieving object
user.getOperationalUnit().size();
//Now you will get childs with your parent entity
UserProxy userProxy = new UserProxy();
BeanUtils.copyProperties(userProxy, user);
return userProxy;
} catch(Exception ex) {
ex.printStackTrace();
return null;
}
}
有关
@Transactional
的更多详细信息,您的服务类上有一个@Transactional
注释,这很好。但是,您是否确实确定事务管理设置正确,并且事务确实在应该启动时启动(例如,在输入方法fetchUserById
之前)?我不太确定。我是否应该采取额外的步骤来确保?调试日志记录或调试。实际上,如果你闯入应该是事务性的方法,你会在堆栈框架中看到负责事务管理的类和方法。尝试在那里放置断点,然后再次运行它,直到发生什么。你有一个@Transactional
在您的服务类上添加注释,这很好。但是您是否确实确定事务管理设置正确,并且事务确实在应该启动时启动(例如,在输入方法fetchUserById
之前)?我不太确定。我是否应该采取额外的步骤来确保?调试日志记录或调试。实际上,如果你闯入应该是事务性的方法,你会在堆栈框架中看到负责事务管理的类和方法。尝试在那里放置一个断点,然后再次运行它,直到发生什么。我尝试了这样做s也是,但我得到了相同的错误。由于它是一对多关系,操作单元也有一组用户,我使用一对多注释保留这些用户。我试图进行初始化和获取大小,但操作单元导致延迟加载错误。我还尝试使用eager进行获取,这会导致Inifinite循环。@Sakib RelatioJPA中的NSHIP始终是单向的,除非您在两个di中都将父级与子级关联