Java Hibernate即使使用@Transactional,也无法在实体服务中延迟初始化角色no会话的集合

Java Hibernate即使使用@Transactional,也无法在实体服务中延迟初始化角色no会话的集合,java,spring,hibernate,annotations,hibernate-onetomany,Java,Spring,Hibernate,Annotations,Hibernate Onetomany,我有一个hibernate项目,它连接到两个数据源,并有一个基本dao。我还使用基本dao为数据源派生通用dao 我有一个获取连接关系的服务,当实体具有一对多关系时,我会遇到以下错误。我陷入了无法获得一对多关系对象的困境 我使用ApacheCommonsBeanutils来复制属性,希望它能够进行深度复制,但它也不起作用。我的想法快用完了 我读到我可以选择在视图中使用OpenSession,但我不确定如何进行 错误 我有以下图层和文件 控制器层 @ApiOperation(value =

我有一个hibernate项目,它连接到两个数据源,并有一个基本dao。我还使用基本dao为数据源派生通用dao

我有一个获取连接关系的服务,当实体具有一对多关系时,我会遇到以下错误。我陷入了无法获得一对多关系对象的困境

我使用ApacheCommonsBeanutils来复制属性,希望它能够进行深度复制,但它也不起作用。我的想法快用完了

我读到我可以选择在视图中使用OpenSession,但我不确定如何进行

错误

我有以下图层和文件

控制器层

    @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中都将父级与子级关联