I need to save several child objects when creating the parent object. Ideally, I want to save them in one transaction, however, I keep getting an org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session
.
In this example, a SubDiscipline has many SubdisciplinePlayers.
I feel that there's something wrong with the mapping
public class Subdiscipline {
private int id;
private int disciplineId;
private String name;
private List<SubdisciplinePlayer> subdisciplinePlayers;
public Subdiscipline() {
}
//standard constructors, getter & setters...
}
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...
}
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]
You have declared composite key with fields disciplineId
& subDisciplineId
for your entity SubdisciplinePlayer
.
Now in your program you are creating 2 instances of SubdisciplinePlayer
with same composite id.
SubdisciplinePlayer sdp = new SubdisciplinePlayer();
sdp.setDisciplineId(sd.getDisciplineId());
sdp.setSubDisciplineId(sd.getId());
SubdisciplinePlayer sdp2 = new SubdisciplinePlayer();
sdp2.setDisciplineId(sd.getDisciplineId());
sdp2.setSubDisciplineId(sd.getId());
So when you call Session.save(sd)
, hibernate observed that you are trying to save 2 instances of SubdisciplinePlayer
and throwing the exception as :
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]
To fix the issue just make sure that the composite id of SubdisciplinePlayer
should have different values as primary key should be unique.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.