簡體   English   中英

保存子對象列表時org.hibernate.NonUniqueObjectException

[英]org.hibernate.NonUniqueObjectException when saving a list of child objects

創建父對象時,我需要保存幾個子對象。 理想情況下,我想將它們保存在一個事務中,但是,我不斷收到org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session

在此示例中,SubDiscipline具有許多SubdisciplinePlayers。

我覺得映射有問題

的POJO:

Subdiscipline.java

public class Subdiscipline {

    private int id;
    private int disciplineId;
    private String name;
    private List<SubdisciplinePlayer> subdisciplinePlayers;

    public Subdiscipline() {
    }

    //standard constructors, getter & setters...
}

SubdisciplinePlayers.java

public class SubdisciplinePlayer implements Serializable {

    private int idPlayers;
    private int disciplineId;
    private int subDisciplineId;
    private int players;
    private int minPlayers;
    private int maxPlayers;

    private Subdiscipline subdiscipline;

    public SubdisciplinePlayer() {
    }
    //standard constructors, getter & setters...
}

Main.java:

public class Main {

    @SuppressWarnings("unchecked")
    public static void main(String[] args) {

        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session session = sf.openSession();
        session.beginTransaction();

        Subdiscipline sd = new Subdiscipline("soccer_" + (new Date()).getTime(), new Date(), new Date(), new Status(1) );
        sd.setDisciplineId(4);
        session.save(sd);

        SubdisciplinePlayer sdp = new SubdisciplinePlayer();
        sdp.setDisciplineId(sd.getDisciplineId());
        sdp.setSubDisciplineId(sd.getId());
        sdp.setSubdiscipline(sd);
        sdp.setIdPlayers(555);

        SubdisciplinePlayer sdp2 = new SubdisciplinePlayer();
        sdp2.setDisciplineId(sd.getDisciplineId());
        sdp2.setSubDisciplineId(sd.getId());
        sdp2.setSubdiscipline(sd);
        sdp2.setIdPlayers(457);

        sd.setSubdisciplinePlayers(new ArrayList<SubdisciplinePlayer>());
        sd.getSubdisciplinePlayers().add(sdp);
        sd.getSubdisciplinePlayers().add(sdp2);

        session.save(sd);

        session.getTransaction().commit();
        session.close();

    }
}

映射

子學科映射

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="net.viralpatel.hibernate.Subdiscipline" table="sub_discipline">
        <id name="id" column="sub_dis_id" unsaved-value="0">
            <generator class="increment"/>
        </id>
        <property name="disciplineId" column="dis_id" type="int"/>
        <property name="name" column="sub_discipline" type="string"/>           
        <bag name="subdisciplinePlayers" table="sdis_players" inverse="true" cascade="all">
            <key column="sub_dis_id" />
            <one-to-many class="net.viralpatel.hibernate.SubdisciplinePlayer" />
        </bag>

    </class>
</hibernate-mapping>

子學科球員映射

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="net.viralpatel.hibernate.SubdisciplinePlayer" table="sdis_players">
        <composite-id>
            <key-property name="disciplineId" column="dis_id" type="int"/>
            <key-property name="subDisciplineId" column="sub_dis_id" type="int" />
        </composite-id>
        <property name="idPlayers" column="id_players" type="int"/>
        <property name="players" column="players" type="int"/>
        <property name="minPlayers" column="min_players" type="int"/>
        <property name="maxPlayers" column="max_players" type="int"/>
        <many-to-one name="subdiscipline" class="net.viralpatel.hibernate.Subdiscipline" cascade="none" insert="false" update="false">
            <column name="sub_dis_id"/>
        </many-to-one>
    </class>
</hibernate-mapping>

拋出異常

Exception in thread "main" org.hibernate.NonUniqueObjectException: a different object     with the same identifier value was already associated with the session:     [net.viralpatel.hibernate.SubdisciplinePlayer#net.viralpatel.hibernate.SubdisciplinePlayer@1cd7e9c3]

您已為實體SubdisciplinePlayer聲明了帶有disciplineId subDisciplineIdsubDisciplineId字段的組合鍵。

現在,在您的程序中,您將創建兩個具有相同組合ID的SubdisciplinePlayer實例。

SubdisciplinePlayer sdp = new SubdisciplinePlayer();
sdp.setDisciplineId(sd.getDisciplineId());
sdp.setSubDisciplineId(sd.getId());

SubdisciplinePlayer sdp2 = new SubdisciplinePlayer();
sdp2.setDisciplineId(sd.getDisciplineId());
sdp2.setSubDisciplineId(sd.getId());

因此,當您調用Session.save(sd) ,hibernate觀察到您正在嘗試保存2個SubdisciplinePlayer實例, SubdisciplinePlayer異常拋出為:

org.hibernate.NonUniqueObjectException: a different objectwith the same identifier 
value was already associated with the session:     
[net.viralpatel.hibernate.SubdisciplinePlayer#
net.viralpatel.hibernate.SubdisciplinePlayer@1cd7e9c3]

要解決此問題,只需確保SubdisciplinePlayer的復合ID應該具有不同的值,因為主鍵應該是唯一的。

當您嘗試第二次保存時,請使用合並而不是保存。

   sd.setSubdisciplinePlayers(new ArrayList<SubdisciplinePlayer>());
   sd.getSubdisciplinePlayers().add(sdp);
   sd.getSubdisciplinePlayers().add(sdp2);
   session.merge(sd);

我為您列出了更多參考。

參考1

參考2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM