无法写入JSON

时间:2018-01-08 15:25:19

标签: json hibernate spring-mvc

您好我是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

1 个答案:

答案 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);
}