hibernate实体到json [英] hibernate entity to json

查看:80
本文介绍了hibernate实体到json的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Hibernate 4和Spring 3.

我有两个实体。

Book entity

p>

  @Entity 
@Table(name =book)
public class Book实现Serializable {

public Book(){
}

private static final long serialVersionUID = 1L;

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

@ManyToOne()
@JoinColumn(name =author_id)
private作者作者;

私人字符串名称;
私人诠释页;

@版本
@Column(name =VERSION)
private int version;

public int getId(){
return id;
}

public void setId(int id){
this.id = id;
}

public作者getAuthor(){
返回作者;
}

public void setAuthor(Author author){
this.author = author;
}

public String getName(){
return name;
}

public void setName(String name){
this.name = name;
}

public int getPages(){
return pages;
}

public void setPages(int pages){
this.pages = pages;
}

public int getVersion(){
return version;
}

public void setVersion(int version){
this.version = version;
}


}

和作者实体

  @Entity 
@Table(name =author)
public class Author实现Serializable {

public Author(){
}

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
私人字符串名称;

@OneToMany(mappedBy =author,cascade = CascadeType.ALL,orphanRemoval = true)
private Set< Book> books = new HashSet< Book>();


public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}

public Set< Book> getBooks(){
返还书籍;
}
public void setBooks(Set< Book> books){
this.books = books;
}

public void addBook(Book book){
book.setAuthor(this);
getBooks()。add(book);
}

public void removeBook(Book book){
getBooks()。remove(book);
}

}

和JSON取决于pom.xml

 <依赖关系> 
< groupId> com.fasterxml.jackson.core< / groupId>
< artifactId> jackson-core< / artifactId>
< version> 2.1.2< / version>
< /依赖关系>


< dependency>
< groupId> com.fasterxml.jackson.datatype< / groupId>
< artifactId> jackson-datatype-hibernate4< / artifactId>
< version> 2.1.2< / version>
< /依赖关系>

我的根上下文在这里 -

 <! - 根上下文:定义对所有其他Web组件可见的共享资源 - > 
< context:annotation-config />

< context:component-scan base-package =org.jar.libs.dao/>
< context:component-scan base-package =org.jar.libs.service/>

< tx:注解驱动的事务管理器=transactionManager/>

< bean id =jspViewResolver
class =org.springframework.web.servlet.view.InternalResourceViewResolver>
< property name =viewClassvalue =org.springframework.web.servlet.view.JstlView/>
< property name =prefixvalue =/ WEB-INF / views //>
< property name =suffixvalue =。jsp/>
< / bean>

class =org.springframework.jdbc.datasource.DriverManagerDataSource
p:driverClassName =com.mysql.jdbc.Driverp :url =jdbc:mysql:// localhost:3306 / hibernate
p:username =rootp:password =root/>

< bean id =sessionFactory
class =org.springframework.orm.hibernate4.LocalSessionFactoryBean>
< property name =dataSourceref =dataSource/>
< property name =annotatedClasses>
< list>
<值> org.jar.libs.domain.Book< /值>
< value> org.jar.libs.domain.Author< / value>
< / list>
< / property>
< property name =hibernateProperties>
<道具>
< prop key =hibernate.dialect> org.hibernate.dialect.MySQLDialect< / prop>
< prop key =hibernate.show_sql> true< / prop>
< prop key =hibernate.hbm2ddl.auto> update< / prop>
< /道具>
< / property>
< / bean>

< bean id =transactionManager
class =org.springframework.orm.hibernate4.HibernateTransactionManager>
< property name =sessionFactoryref =sessionFactory/>
< / bean>

< / beans>

... servlet-context.xml

 <! - 启用Spring MVC @Controller编程模型 - > 
< annotation-driven />

<! - 通过高效地提供$ {webappRoot} / resources目录中的静态资源来处理/ resources / **的HTTP GET请求 - >
< resource mapping =/ resources / **location =/ resources //>

<! - 解析@Controllers为/ WEB-INF / views目录中的.jsp资源选择渲染的视图 - >
< beans:bean class =org.springframework.web.servlet.view.InternalResourceViewResolver>
< beans:property name =prefixvalue =/ WEB-INF / views //>
< beans:property name =suffixvalue =。jsp/>
< / beans:bean>

< context:component-scan base-package =org.jar.libs.controller/>

控制器。

  @Controller 
@RequestMapping(value =books / rest)
public class BookController {
$ b $ @Autowired
private BookService bookService;

// logger
private static final Logger logger = LoggerFactory.getLogger(BookController.class);


@SuppressWarnings(unchecked)
@RequestMapping(method = RequestMethod.GET)
public @ResponseBody List< Book> getBook(){


列表< Book> res = bookService.findAll();
return res;




$ b

findAll在我的DAO中:

  public List< Book> findAll(){
Session session = sessionFactory.getCurrentSession();
列表< Book> result =(List< Book>)session.createQuery(从书c选择c)。
返回结果;

在调试中,我看到该方法返回2条记录,但Spring无法将结果到JSON并返回406 HTTP错误。怎么了?



我附上了我在调试中看到的图片。 - http://tinypic.com/view.php?pic=35kvi9i&s= 6

解决方案

通常,当您调用实体类的getter方法(返回关系对象)那么你得到 LazyInitializationException s。



如果您将实体类对象(从查询中检索到)转换为json 不在事务中,那么可能会发生这种情况。 p>

我有同样的问题,我将通过休眠检索到的实体对象转换为控制器中的json。由于控制器没有事务处理(Transaction at service layer),在转换为json时,实体类对象的getter方法被调用,并且我得到了 LazyInitializationException



我的解决方案,试试这个:

<$ p $
@RequestMapping(method = RequestMethod.GET)
public @ResponseBody List< Book>< code> @SuppressWarnings(unchecked getBook(){
列表< Book> res = bookService.findAll();
for(Book book:res){
book.getAuthor()。setBooks(null);
}
return res;
}


i use Hibernate 4 and Spring 3.

i have two entity.

Book entity

@Entity
@Table(name = "book")
public class Book implements Serializable {

    public Book() {
    }

    private static final long serialVersionUID = 1L;

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

    @ManyToOne()
    @JoinColumn( name = "author_id" )
    private Author author;

    private String name;
    private int pages;

    @Version
    @Column( name = "VERSION")
    private int version;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Author getAuthor() {
        return author;
    }

    public void setAuthor(Author author) {
        this.author = author;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPages() {
        return pages;
    }

    public void setPages(int pages) {
        this.pages = pages;
    }

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }


}

and Author entity

@Entity
@Table(name = "author")
public class Author implements Serializable {

    public Author() {
    }

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue( strategy = GenerationType.IDENTITY)
    private int id;
    private String name;

    @OneToMany( mappedBy = "author", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<Book> books = new HashSet<Book>();


    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public Set<Book> getBooks() {
        return books;
    }
    public void setBooks(Set<Book> books) {
        this.books = books;
    }

    public void addBook(Book book) {
        book.setAuthor(this);
        getBooks().add(book);
    }

    public void removeBook(Book book) {
        getBooks().remove(book);        
    }

}

and JSON depend in pom.xml

<dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.1.2</version>
        </dependency>


        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-hibernate4</artifactId>
            <version>2.1.2</version>
        </dependency>

My Root-context is here -

    <!-- Root Context: defines shared resources visible to all other web components -->
    <context:annotation-config/>

    <context:component-scan base-package="org.jar.libs.dao" />
    <context:component-scan base-package="org.jar.libs.service" />

    <tx:annotation-driven transaction-manager="transactionManager" />

     <bean id="jspViewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource"
        p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost:3306/hibernate"
        p:username="root" p:password="root" />

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>org.jar.libs.domain.Book</value>
                <value>org.jar.libs.domain.Author</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

</beans>

...servlet-context.xml

<!-- Enables the Spring MVC @Controller programming model -->
    <annotation-driven />

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>

    <context:component-scan base-package="org.jar.libs.controller" />

Controller.

@Controller
@RequestMapping (value = "books/rest")
public class BookController {

    @Autowired
    private BookService bookService;

    // logger
    private static final Logger logger = LoggerFactory.getLogger(BookController.class);


    @SuppressWarnings("unchecked")
    @RequestMapping( method = RequestMethod.GET )
    public @ResponseBody List<Book> getBook() {


        List<Book> res = bookService.findAll();
        return res;


    }

}

findAll in my DAO :

public List<Book> findAll() {
        Session session = sessionFactory.getCurrentSession();
        List<Book> result = (List<Book>) session.createQuery("select c from Book c").list();
        return result;
    }

in debug i see that method return 2 records, but Spring can not convert result to JSON and return 406 HTTP error. What's wrong?

I attach image what i see in debug. - http://tinypic.com/view.php?pic=35kvi9i&s=6

解决方案

Generally, when you call getter methods of entity classes(which returns relation object) out of transaction, then you get LazyInitializationExceptions.

That's what might be happening in your case if you are converting entity class objects(retrieved from query) to json out of transaction.

I had same issue, I converted my entity object retrieved by hibernate to json in controller. As controller was out of transaction(Transaction at service layer), while converting to json, getter methods of entity class objects are called and I got LazyInitializationException. Which obstructed object conversion to json, and response was not returned.

My solution, Try this :

@SuppressWarnings("unchecked")
@RequestMapping( method = RequestMethod.GET )
public @ResponseBody List<Book> getBook() {
    List<Book> res = bookService.findAll();
    for(Book book : res) {
       book.getAuthor().setBooks(null);
    }
    return res;
}

这篇关于hibernate实体到json的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆