多对多集 - 添加条目 - org.hibernate.HibernateException:找到对集合的共享引用:

Posted

技术标签:

【中文标题】多对多集 - 添加条目 - org.hibernate.HibernateException:找到对集合的共享引用:【英文标题】:many to many set - add entry - org.hibernate.HibernateException: Found shared references to a collection: 【发布时间】:2014-11-26 11:32:42 【问题描述】:

我只需要使用hibernate(将歌曲关联到播放列表)在多对多表/对象上添加一个名为SongsPlaylist 的条目。

表的结构是这样定义的:Songs---->SongPlaylist<----Playlists

映射文件(省略不重要的文件部分):

<hibernate-mapping>
    <class name="model.pojo.Songs" table="songs" catalog="dbname" lazy="false">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <set name="songsPlaylists" table="songs_playlist" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="song" not-null="true" unique="true" />
            </key>
            <one-to-many class="model.pojo.SongsPlaylist" />
        </set>
    </class>
</hibernate-mapping>
<!-- Generated 24-set-2014 8.40.14 by Hibernate Tools 3.6.0 -->
<hibernate-mapping>
    <class name="model.pojo.SongsPlaylist" table="songs_playlist" catalog="dbname" lazy="false">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <many-to-one name="songs" class="model.pojo.Songs" fetch="select">
            <column name="song" not-null="true" unique="true" />
        </many-to-one>
        <many-to-one name="playlists" class="model.pojo.Playlists" fetch="select">
            <column name="playlist" not-null="true" unique="true" />
        </many-to-one>
    </class>
</hibernate-mapping>

<!-- Generated 24-set-2014 8.40.14 by Hibernate Tools 3.6.0 -->
<hibernate-mapping>
    <class name="model.pojo.Playlists" table="playlists" catalog="dbname" lazy="false">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <set name="songsPlaylists" table="songs_playlist" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="playlist" not-null="true" unique="true" />
            </key>
            <one-to-many class="model.pojo.SongsPlaylist" />
        </set>
    </class>
</hibernate-mapping>

pojo 类:

public class SongsPlaylist  implements java.io.Serializable 
     private Integer id;
     private Songs songs;
     private Playlists playlists;
     (...)


public class Songs  implements java.io.Serializable 
     private Integer id;
     private Set songsPlaylists = new HashSet(0);
     (...)


public class Playlists  implements java.io.Serializable 
     private Integer id;
     private Set songsPlaylists = new HashSet(0);
     (...)

这是我的功能

            s = new HibernateUtil().getSessionFactory().openSession();
            transaction = s.beginTransaction();
            (...)
                q = s.createQuery("select sp from SongsPlaylist sp where sp.playlists = :p");
                q.setParameter("p", p);
                sp = q.list();
                //already exists a song binded to that playlist
            if(sp.size()>0)
                Set<Playlists> sP = sp.get(0).getPlaylists().getSongsPlaylists();
                sP.add(p);
                song.setSongsPlaylists(sP);
                s.save(s);
            else
                //or it is in another playlist...
                q = s.createQuery("select sp from SongsPlaylist sp where sp.songs = :s");
                q.setParameter("s", song);
                sp = q.list();
                if(sp.size()>0)
                    Set<Songs> sP = sp.get(0).getSongs().getSongsPlaylists();
                    sP.add(song);
                    p.setSongsPlaylists(sP);
                    s.save(p);
                else
                    s.save(new SongsPlaylist(song, p));
                
            
            
            transaction.commit();
            s.close();

它卡在transaction.commit();(最后几行)

org.hibernate.HibernateException: Found shared references to a collection: 
model.pojo.Songs.songsPlaylists

在持久化对象上持久化 Set&lt;Playlists 时,我似乎做错了什么(当我尝试使用 Set&lt;Songs&gt; 这样做时也是如此)。为了插入“SongPlaylist”并避免提到的休眠异常,这种情况的最佳做法是什么?

【问题讨论】:

显示你的映射文件? 你看过映射文件吗? ***.com/questions/1692871/… 我已经完成了您提供的链接中的建议。现在它转到原因:com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:键“播放列表”的重复条目“2”;多对多表具有引用歌曲和播放列表表的索引。如何避免允许重复输入键? 为了在歌曲和播放列表之间建立多对多关系,我的 hbm 文件是否正确? 【参考方案1】:

找到了解决办法...

在 else 块中(而不是我写的),现在是:

Set<Playlists> sP = song.getPlaylistses(); // terrific netbeans naming when automatic pojo mapping :-)
sP.add(p);
song.setPlaylistses(sP);
s.save(song);

只是一个附带错误,与这个无关,但是

SongsPlaylist 不应为 hbm 文件。应该改为休眠映射

<hibernate-mapping>
    <class name="model.pojo.Songs" table="songs" catalog="dbname" lazy="false">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        (...)
        <set name="playlistses" table="songs_playlist" inverse="false" lazy="false" fetch="select">
            <key>
                <column name="song" not-null="true" />
            </key>
            <many-to-many entity-name="model.pojo.Playlists">
                <column name="playlist" not-null="true" />
            </many-to-many>
        </set>
    </class>
</hibernate-mapping>


<hibernate-mapping>
    <class name="model.pojo.Playlists" table="playlists" catalog="dbname" lazy="false">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <set name="songses" table="songs_playlist" inverse="false" lazy="false" fetch="select">
            <key>
                <column name="playlist" not-null="true" />
            </key>
            <many-to-many entity-name="model.pojo.Songs">
                <column name="song" not-null="true" />
            </many-to-many>
        </set>
    </class>
</hibernate-mapping>

【讨论】:

以上是关于多对多集 - 添加条目 - org.hibernate.HibernateException:找到对集合的共享引用:的主要内容,如果未能解决你的问题,请参考以下文章

实体框架在多对多关系中重复条目

防止 SQLAlchemy 中多对多关系中的重复表条目

ASP.NET Core MVC:在发布编辑方法之前删除多对多条目

一对一与多对多与重复条目

Django 管理中的多对多:选择无

优化查询以匹配和排除多个多对多条目