您好我是hibernate的新手。我在春天和JSON合作。我想以JSON格式显示用户的详细信息,但我在那里遇到了一些错误。 我的错误是:
HTTP状态500 - 内部服务器错误
输入例外报告
messageInternal Server Error
description服务器遇到内部错误,导致无法完成此请求。
例外
org.springframework.http.converter.HttpMessageNotWritableException:无法编写JSON:懒得初始化角色集合:com.nishan.lifestyle.entity.User.pictureList,无法初始化代理 - 无会话;嵌套异常是com.fasterxml.jackson.databind.JsonMappingException:懒得初始化一个角色集合:com.nishan.lifestyle.entity.User.pictureList,无法初始化代理 - 没有Session(通过引用链:java.util。 ArrayList的[0] -
com.nishan.lifestyle.entity.User [" pictureList"]) note备注GlassFish Server Open Source Edition 4.1.1日志中提供了异常的完整堆栈跟踪及其根本原因。
GlassFish Server Open Source Edition 4.1.1
我使用了以下方法来获取所有用户的详细信息
public List<T> getAll() {
session = sessionFactory.openSession();
Criteria criteria = session.createCriteria(persistClass);
List<T> list = criteria.list();
session.close();
return list;
}
//getting JSON file
@RequestMapping(value = "/api/customer/customer-details", method = RequestMethod.GET)
public @ResponseBody List<User> getUserId() {
return customerDaoImp.getAll();
}
User.java-实体类
@Entity
@Table(name = "tbl_user", catalog = "lifestyle", schema = "")
@NamedQueries({
@NamedQuery(name = "User.findAll", query = "SELECT u FROM User u")
, @NamedQuery(name = "User.findByUserId", query = "SELECT u FROM User u WHERE u.userId = :userId")
, @NamedQuery(name = "User.findByFullName", query = "SELECT u FROM User u WHERE u.fullName = :fullName")
, @NamedQuery(name = "User.findByAddress", query = "SELECT u FROM User u WHERE u.address = :address")
, @NamedQuery(name = "User.findByContact", query = "SELECT u FROM User u WHERE u.contact = :contact")
, @NamedQuery(name = "User.findByGender", query = "SELECT u FROM User u WHERE u.gender = :gender")
, @NamedQuery(name = "User.findByDob", query = "SELECT u FROM User u WHERE u.dob = :dob")
, @NamedQuery(name = "User.findByEmail", query = "SELECT u FROM User u WHERE u.email = :email")
, @NamedQuery(name = "User.findByPassword", query = "SELECT u FROM User u WHERE u.password = :password")
, @NamedQuery(name = "User.findByActive", query = "SELECT u FROM User u WHERE u.active = :active")
, @NamedQuery(name = "User.findByCreatedDate", query = "SELECT u FROM User u WHERE u.createdDate = :createdDate")})
public class User implements Serializable {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "userId")
private List<Picture> pictureList;
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Integer userId;
@Column(name = "full_name")
private String fullName;
@Column(name = "address")
private String address;
@Column(name = "contact")
private String contact;
@Column(name = "gender")
private String gender;
@Column(name = "dob")
@Temporal(TemporalType.DATE)
private Date dob;
// @Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email")//if the field contains email address consider using this annotation to enforce field validation
@Column(name = "email")
private String email;
@Column(name = "password")
private String password;
@Column(name = "active", insertable = false)
private short active;
@Column(name = "created_date", insertable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date createdDate;
public User() {
}
public User(Integer userId) {
this.userId = userId;
}
public User(Integer userId, String fullName, String email, String password, short active) {
this.userId = userId;
this.fullName = fullName;
this.email = email;
this.password = password;
this.active = active;
}
//getter and setter
Picture.java - 实体类
@Entity
@Table(name = "tbl_picture")
@NamedQueries({
@NamedQuery(name = "Picture.findAll", query = "SELECT p FROM Picture p")
, @NamedQuery(name = "Picture.findByPictureId", query = "SELECT p FROM Picture p WHERE p.pictureId = :pictureId")
, @NamedQuery(name = "Picture.findByPictureName", query = "SELECT p FROM Picture p WHERE p.pictureName = :pictureName")})
public class Picture implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "picture_id")
private Integer pictureId;
@Column(name = "picture_name")
private String pictureName;
@JoinColumn(name = "user_id", referencedColumnName = "user_id")
@ManyToOne(optional = false)
private User userId;
public Picture() {
}
public Picture(Integer pictureId) {
this.pictureId = pictureId;
}
public Picture(Integer pictureId, String pictureName) {
this.pictureId = pictureId;
this.pictureName = pictureName;
}
//getter and setter
答案 0 :(得分:1)
更改
@OneToMany(cascade = CascadeType.ALL, mappedBy = "userId")
private List<Picture> pictureList;
到(解决方法)
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "userId")
private List<Picture> pictureList;
为什么要解决?
请记住@OneToMany默认使用FetchType.LAZY,这意味着默认情况下集合是延迟加载的,但更改为EAGER会带来另一个问题。将加载所有集合。
Hibernate Docs建议默认使用LAZY,修复此问题的另一种方法是添加HibernateModule并配置来处理这种情况。
https://github.com/FasterXML/jackson-datatype-hibernate
以下是如何实施该模块:
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
Hibernate5Module hibernate5Module = new Hibernate5Module();
hibernate5Module.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
hibernate5Module.configure(Hibernate5Module.Feature.FORCE_LAZY_LOADING, false);
objectMapper.registerModule(hibernate5Module);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); //optional
messageConverter.setObjectMapper(objectMapper);
return messageConverter;
}
然后在您的类中扩展WebMvcConfigurerAdapter
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(mappingJackson2HttpMessageConverter());
super.configureMessageConverters(converters);
}