gpt4 book ai didi

java - org.hibernate.NonUniqueObjectException 保存子对象列表时

转载 作者:行者123 更新时间:2023-11-30 07:05:59 25 4
gpt4 key购买 nike

创建父对象时需要保存几个子对象。理想情况下,我想将它们保存在一个事务中,但是,我不断收到 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...
}

主.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 声明了包含字段 disciplineIdsubDisciplineId 的复合键。

现在在您的程序中,您正在创建 2 个具有相同复合 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 观察到您正在尝试保存 SubdisciplinePlayer 的 2 个实例并抛出异常:

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

关于java - org.hibernate.NonUniqueObjectException 保存子对象列表时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26133022/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com