У меня есть эта ошибка при использовании 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 из-за его меньшего использования памяти и т. Д.
Есть ли другой способ заставить мой ajax работать с помощью LAZY? Любая помощь очень ценится.
=============================================== ==========================
UPDATE
Вот мой класс 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);
}
}
@ Бушра Ханнур, спасибо, я случайно ударил код в Дао, я включил
для (пользователь: пользователи) {
Hibernate.initialize (user.getUserProfiles ()); }
затем снова измените FetchType на LAZY, и я могу без проблем использовать мой вызов ajax. извините за мой нубский вопрос.
Но я не могу понять, как он переопределил метод. в нем говорится, что получение будет ОЧЕНЬ, но я не могу полностью понять. но почему-то это работает даже сейчас, даже класс модели установил его в LAZY.
что касается ссылки на этот код, то здесь ссылка: http://websystique.com/springmvc/spring-mvc-4-and-spring-security-4-integration-example/