创建父对象时,我需要保存几个子对象。理想情况下,我想将它们保存在一个事务中,但是,我一直得到org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session

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

我觉得映射有问题

POJO:

子学科.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]

最佳答案

您已经为实体disciplineId的字段subDisciplineIdSubdisciplinePlayer声明了组合键。

现在,在您的程序中,您将创建两个具有相同复合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实例并将异常抛出为:

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应该具有不同的值,因为主键应该是唯一的。

08-08 06:00