无法写内容:懒得初始化角色集合,无法初始化代理 - 没有会话

时间:2018-04-25 05:30:27

标签: javascript ajax hibernate spring-mvc eager

使用 FetchType.LAZY

时出现此错误
  

无法写内容:懒得初始化一个集合   角色:com.websystique.springmvc.model.User.userProfiles,不可以   初始化代理 - 没有会话

这是我的模特课:

@SuppressWarnings("serial")
@Entity
@Table(name="APP_USER")
public class User implements Serializable{

    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;

    @NotEmpty
    @Column(name="SSO_ID", unique=true, nullable=false)
    private String ssoId;

    @NotEmpty
    @Column(name="PASSWORD", nullable=false)
    private String password;

    @NotEmpty
    @Column(name="FIRST_NAME", nullable=false)
    private String firstName;

    @NotEmpty
    @Column(name="LAST_NAME", nullable=false)
    private String lastName;

    @NotEmpty
    @Column(name="EMAIL", nullable=false)
    private String email;

    @NotEmpty
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "APP_USER_USER_PROFILE", 
             joinColumns = { @JoinColumn(name = "USER_ID") }, 
             inverseJoinColumns = { @JoinColumn(name = "USER_PROFILE_ID") })
    private Set<UserProfile> userProfiles = new HashSet<UserProfile>();

    getters/setters ....

这是我的javascript ajax:

/* Populate DataTable of list of all User existed using ajax */
function populateUserDataTable() {
    $("#dataTables-example").dataTable().fnDestroy();

    /* set class and onClick event listener */
    var buttonEditClass = 'class="btn btn-success" data-toggle="modal"';
    buttonEditClass += 'data-target="#modalAddCargoUser"';
    buttonEditClass += 'onClick="searchCargoDetailViaAjax(this)"';

    var buttonDeleteClass = 'class="btn btn-danger" data-toggle="modal"';
    buttonDeleteClass += 'data-target="#modalDeleteCargoUser"';
    buttonDeleteClass += 'onClick="fetchDeleteId(this)"'

    $
            .ajax({
                'url' : '' + myContext + '/ajaxUserList',
                'method' : "GET",
                'contentType' : 'application/json'
            })
            .done(
                    function(data) {
                        var dataToString = JSON.stringify(data);
                        $('#dataTables-example')
                                .dataTable(
                                        {
                                            responsive : true,
                                            "aaData" : data,
                                            "columns" : [
                                                    {
                                                        "data" : "firstName"
                                                    },
                                                    {
                                                        "data" : "lastName"
                                                    },
                                                    {
                                                        "data" : "email"
                                                    },

                                                    {
                                                        "data" : "ssoId"
                                                    },

                                                    {

                                                        /*
                                                         * Add button to
                                                         * dataTable
                                                         */
                                                        sortable : false,
                                                        "render" : function(
                                                                data, type,
                                                                full, meta) {
                                                            var buttonID = full.ssoId;
                                                            var drawActionButton = ' <button id='
                                                                    + buttonID
                                                                    + ' '
                                                                    + buttonEditClass
                                                                    + ' >Edit</button> ';
                                                            drawActionButton += ' <button id='
                                                                    + buttonID
                                                                    + ' '
                                                                    + buttonDeleteClass
                                                                    + ' >Delete</button> ';
                                                            return drawActionButton;
                                                        }
                                                    } ]
                                        })
                    });
}

我的控制器类:

/*
     * This method will redirect user page
     */
    @RequestMapping(value = { "/ajaxUserList" }, method = RequestMethod.GET)
    @ResponseBody
    public List<User> ajaxUserList(ModelMap model) {
        /* Populate DataTable */
        List<User> users = userService.findAllUsers();
        model.addAttribute("loggedinuser", getPrincipal());
        return users;
    }

我的服务类:

@Service("userService")
@Transactional
public class UserServiceImpl implements UserService{

    @Autowired
    private UserDao dao;

    public List<User> findAllUsers() {
        return dao.findAllUsers();
    }


}

但是,当我更改 FetchType.EAGER 时,它可以正常工作。我也尝试阅读EAGER和LAZY之间的区别,我认为在我的情况下我更喜欢使用LAZY,因为它的内存使用量更少等。

还有其他方法如何使用LAZY让我的ajax工作?非常感谢任何帮助。

=============================================== ========================== 的更新

这是我的UserDaoImpl类:

@Repository("userDao")
public class UserDaoImpl extends AbstractDao<Integer, User> implements UserDao {

    static final Logger logger = LoggerFactory.getLogger(UserDaoImpl.class);

    public User findById(int id) {
        User user = getByKey(id);
        if(user!=null){
            Hibernate.initialize(user.getUserProfiles());
        }
        return user;
    }

    @SuppressWarnings("unchecked")
    public List<User> findAllUsers() {
        Criteria criteria = createEntityCriteria().addOrder(Order.asc("firstName"));
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);//To avoid duplicates.
        List<User> users = (List<User>) criteria.list();

        // No need to fetch userProfiles since we are not showing them on list page. Let them lazy load. 
    // Uncomment below lines for eagerly fetching of userProfiles if you want.

    /*for(User user : users){
        Hibernate.initialize(user.getUserProfiles());
    }*/

        return users;
    }   

}

AbstractDao类:

public abstract class AbstractDao<PK extends Serializable, T> {

    private final Class<T> persistentClass;

    @SuppressWarnings("unchecked")
    public AbstractDao() {
        this.persistentClass = (Class<T>) ((ParameterizedType) this.getClass()
                .getGenericSuperclass()).getActualTypeArguments()[1];
    }

    @Autowired
    private SessionFactory sessionFactory;

    protected Session getSession(){
        return sessionFactory.getCurrentSession();
    }

    @SuppressWarnings("unchecked")
    public T getByKey(PK key) {
        return (T) getSession().get(persistentClass, key);
    }

    public void persist(T entity) {
        getSession().persist(entity);
    }

    public void delete(T entity) {
        getSession().delete(entity);
    }

    public void update(T entity){
        getSession().update(entity);
    }

    protected Criteria createEntityCriteria(){
        return getSession().createCriteria(persistentClass);
    }



}

@ Bushra Hannure谢谢你,我不小心撞到了Dao中的代码我启用了

  

for(User user:users){             状态,Hibernate.initialize(user.getUserProfiles()); }

然后再次将FetchType更改为LAZY,我可以毫无问题地使用我的ajax调用。对不起我的noob问题。

但是我无法承认它是如何覆盖该方法的。它说获取将是EAGERLY但我完全不明白。但不知何故,即使现在模型类将其设置为LAZY,它也能正常工作。

此代码的引用是链接:http://websystique.com/springmvc/spring-mvc-4-and-spring-security-4-integration-example/

1 个答案:

答案 0 :(得分:0)

您的应用程序配置不允许在视图中使用Hibernate会话。在请求完成之后和渲染视图之前,会话正在关闭。

FetchType.EAGER在呈现视图和应用程序正常工作之前加载请求中的所有数据。 FetchType.LAZY按需加载数据 - 在视图中这样就可以获得Hibernate异常,因为此时会话已关闭。

例如,对于Spring Boot配置是:

spring.jpa.open-in-view: true