JPA一对多关系重复数据问题导致的查询错误BeanSerializer
本文由发表于6年前 | J2EE | 暂无评论 |  被围观 5,587 views+
JPA重复数据问题:使用Jackson框架转换:
JPA重复数据问题:

两个实体类:

package com.itzhai.musicsystem.bean;

import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name="t_user")
public class User {
    @Id
    @Column(name = "user_id")
    private String username;
    @Column(name = "user_nikename", length=100)
    private String nikename;
    @Column(name = "user_password", length=20)
    private String password;
    @Column(name = "user_email", length=40)
    private String email;
    //@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, mappedBy = "creater", fetch = FetchType.EAGER)
    //单向一对多
    @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE, CascadeType.REMOVE }, fetch = FetchType.EAGER, mappedBy = "creater") 
    private Set<Album> albums;

    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }

    public String getNikename() {
        return nikename;
    }
    public void setNikename(String nikename) {
        this.nikename = nikename;
    }

    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }

    public Set<Album> getAlbums() {
        return albums;
    }
    public void setAlbums(Set<Album> albums) {
        this.albums = albums;
    }

}
package com.itzhai.musicsystem.bean;

import java.util.Date;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name="t_album")
public class Album {

    @Id
    @Column(name = "album_id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int albumId=0;

    @Column(name = "album_name", length=100)
    private String albumName;

    @Column(name = "album_createtime", length=20)
    private Date createTime;

    @ManyToOne(cascade = { CascadeType.REFRESH, CascadeType.MERGE }, optional = false)
    @JoinColumn(name = "user_id")
    private User creater;

    //@Column(name = "album_musics")
    //@OneToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
    @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
    @JoinTable(name = "t_album_t_music", 
            joinColumns = { @JoinColumn(name = "t_album_id", referencedColumnName = "album_id") },
            inverseJoinColumns = { @JoinColumn(name = "t_music_id", referencedColumnName = "music_id") })
    private Set<Music> musics;

    public int getAlbumId() {
        return albumId;
    }
    public void setAlbumId(int albumId) {
        this.albumId = albumId;
    }

    public String getAlbumName() {
        return albumName;
    }
    public void setAlbumName(String albumName) {
        this.albumName = albumName;
    }

    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public User getCreater() {
        return creater;
    }
    public void setCreater(User creater) {
        this.creater = creater;
    }

    public Set<Music> getMusics() {
        return musics;
    }
    public void setMusics(Set<Music> musics) {
        this.musics = musics;
    }
}
使用Jackson框架转换:
        ObjectMapper objectMapper = new ObjectMapper();
        JsonGenerator jsonGenerator = null;
        String result;
        try {
            jsonGenerator = objectMapper.getJsonFactory().createJsonGenerator(System.out, JsonEncoding.UTF8);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        QueryResult<Album> albumList = new QueryResult<Album>();
        albumList = ManagerHelper.getAlbumManager().getScrollData(Album.class);

        try {
            jsonGenerator.writeObject(albumList.getResultlist());
        } catch (JsonProcessingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

发现得出如下的数据:

[{"albumId":1,"musics":[{"id3v1":"TAG","songName":"红日\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000","artist":"李克勤\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000","album":"留住这一刻-李克勤1\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000","genre":0,"musicUrl":"http://localhost/music/李克勤-红日.mp3","id":7,"size":4643195,"comment":"\u0000\u0001\f                         ","year":"\u0000\u0000\u0000\u0000"}],"albumName":"abcdefg","createTime":1335692164000,"creater":{"username":"arthinking","nikename":"abc","email":"arthinking@qq.com","albums":[{"albumId":2,"musics":[{"id3v1":"TAG","songName":"千千厥歌\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000","artist":"陳慧嫻\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000","album":"柔情金曲精装集\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000","genre":0,"musicUrl":"http://localhost/music/陈慧娴 - 千千厥歌.mp3","id":15,"size":8436425,"comment":"\u0000\u0000?\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000","year":"\u0000\u0000\u0000\u0000"}],"albumName":"gggggsfeffs","createTime":1335693885000,"creater":{"username":"arthinking","nikename":"abc","email":"arthinking@qq.com","albums":[{"albumId":2,"musics":[{"id3v1":"TAG","songName":"千千厥歌\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000","artist":"陳慧嫻\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000","album":"柔情金曲精装集\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000","genre":0,"musicUrl":"http://localhost/music/陈慧娴 - 千千厥歌.mp3","id":15,"size":8436425,"comment":"\u0000\u0000?\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000","year":"\u0000\u0000\u0000\u0000"}],"albumName":"gggggsfeffs","createTime":1335693885000,"creater":{"username":"arthinking","nikename":"abc","email":"arthinking@qq.com","albums":[{"albumId":2,"musics":[{"id3v1":"TAG","songName":"千千厥歌\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000","artist":"陳慧嫻\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000","album":"柔情金曲精装集\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000","genre":0,"musicUrl":"http://localhost/music/陈慧娴 - 千千厥歌.mp3","id":15,"size":8436425,"comment":"\u0000\u0000?\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000","year":"\u0000\u0000\u0000\u0000"}],"albumName":"gggggsfeffs","createTime":1335693885000,"creater":{"username":"arthinking","nikename":"abc","email":"arthinking@qq.com",此处省略n个字

之后便是一直报错:

at org.codehaus.jackson.map.ser.BeanSerializer.serializeFields(BeanSerializer.java:175)

从输出的结果可以看出是查处了不断重复的数据。

经过进一步分析发现上面的数据中Album中的creater里面又有Album,这样不断的重复获取数据,就形成了无限循环。

为了解决这个问题,就是让use成为维护端,这样从user这边查出的所有Album就不会重复了。

或者改成由Album到user的多对一关系,而不是由create到Album的一对多关系,既是把user中的album集合删除,Album成为维护端:

保留Album中的配置即可,这样就可以从Album端查出数据了。生成的表只是在t_album加了个user_id外键。

根据表的模型进行配置,不要为了ORM而ORM。根据自己的需要选择合理的配置和查询方法,这样才能写出高效的查询代码。根据自己的表的设计,查阅到到相关的配置方法进行配置,这样才能从本质上提高自己的数据库设计能力。
除了文章中有特别说明,均为IT宅原创文章,转载请以链接形式注明出处。
本文链接:http://www.itzhai.com/the-inquiries-errors-beanserializer-resulting-from-duplicate-data-of-one-to-many-relationship-in-jpa.html
关键字: ,
arthinking Java技术交流群:280755654,入门群:428693174 more
分享到:
 
2012 5/6
如果您有更好的原创技术博文或者观点,欢迎投稿:admin@itzhai.com,或者关注订阅左侧浮动面板的微信号订阅IT宅itread)发送消息。
文章评论
    没有评论
给我留言

有人回复时邮件通知我
J2EE的相关文章
随机文章 本月热门 热评
1 Tips:ItzDesktop使用技巧 2012/6/10
2 C++语法笔记 – C++程序的结构 2011/9/3
3 C++语法笔记 – 函数 2011/9/3
4 Java笔记 – 数组 一维数组 多维数组 数组与泛型 数组实用功能 2014/3/14
5 对象引用循环导致的 net.sf.json.JSONException: There is a cycle in the hierarchy 2013/5/30
6 web网站项目编写页面时需要注意的事项 2011/5/15
友情推荐 更多
破博客 文官洗碗安天下,武将打怪定乾坤。多么美好的年代,思之令人泪落。
Mr.5's Life 白天是一名程序员,晚上就是个有抱负的探索者
行知-追寻技术之美 关注大数据,分布式系统
我爱编程 编程成长轨迹
Cynthia's Blog 学习笔记 知识总结 思考感悟
 
猜您喜欢
欢迎关注我的公众号 IT宅
关于IT宅 文章归档

IT宅中的文章除了标题注明转载或有特别说明的文章,均为IT宅的技术知识总结,学习笔记或随笔。如果喜欢,请使用文章下面提供的分享组件。转载请注明出处并加入文章的原链接。 感谢大家的支持。

联系我们:admin@itzhai.com

Theme by arthinking. Copyright © 2011-2015 IT宅.com 保留所有权利.