Java Hibernate 级联问题
Posted
技术标签:
【中文标题】Java Hibernate 级联问题【英文标题】:Java Hibernate Cascading Issue 【发布时间】:2011-12-31 14:51:01 【问题描述】:----介绍信息和问题域----
基本上我在数据库中有 3 个表:'User'、'Item'、'ItemsPerUser'。
表用户:
用户名(PK); 密码; 电子邮件
表格项
名称(PK)
表 ItemsPerUser
用户名(PK)(和 FK); item_name(PK)(和 FK)
当我不使用级联时,我收到一个错误:“无法添加或更新子行:外键约束失败”。
映射文件正确。我需要某种级联。当我在 多对多关系 的 set 属性中添加级联以将不存在的数据添加到用户和项目时,它会起作用,但它会覆盖 ItemsPerUser 中的数据.每当我保存一个包含一个或多个已在 ItemsPerUser 中输入的项目的对象时,它会覆盖该行,即使 PK 的另一部分不是同一个用户。因此,基本上具有该“项目”的先前用户被具有相同项目的新用户覆盖。 如果它是一个新用户,它应该总是在表 ItemsPerUser 中添加一个新行,即使有一个或多个项目已经被另一个用户对象输入。
---- 视觉样式示例----
假设我从一个空数据库开始,我插入了一个新用户 Roger,他有两个项目:咖啡和水。这是一个发生的例子(Hibernate 正确处理):
User ItemsPerUser Item
Roger Roger-coffee coffee
Roger-water water
现在,当我插入一个拥有咖啡和苏打水的新用户“Alfonzo”时,会发生这种情况:
User ItemsPerUser Item
Roger Alfonzo-coffee coffee
Alfonzo Roger-water water
Alfonzo-soda soda
---- 代码示例----
//Mapping for databag 'User' - !! NOTE: I have deleted the cascade rule in the XML
<hibernate-mapping>
<class name="databag.User" table="User" catalog="androiddb">
<id name="username" type="string">
<column name="username" length="45" />
<generator class="assigned" />
</id>
<property name="password" type="string">
<column name="password" length="45" not-null="true" />
</property>
<property name="email" type="string">
<column name="email" length="45" not-null="true" unique="true" />
</property>
<set name="items" inverse="false" table="itemsperuser">
<key>
<column name="username" length="45" not-null="true" />
</key>
<many-to-many entity-name="databag.Items">
<column name="item_name" length="45" not-null="true"/>
</many-to-many>
</set>
</class>
</hibernate-mapping>
//Mapping for Item
<hibernate-mapping>
<class name="databag.Item" table="item" catalog="androiddb">
<id name="name" type="string">
<column name="name" length="45" />
<generator class="assigned" />
</id>
<set name="users" inverse="false" table="itemsperuser">
<key>
<column name="item_naam" length="45" not-null="true" />
</key>
<many-to-many entity-name="databag.User">
<column name="username" length="45" not-null="true" />
</many-to-many>
</set>
</class>
</hibernate-mapping>
//Saving an object
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction trans = session.beginTransaction();
session.save((User)o);
trans.commit();
session.close();
注意:'(User)o' 不包含一个或多个项目。
【问题讨论】:
向我们展示您的实体、它们的映射以及您正在执行的代码。告诉我们您认为它应该做什么,以及它实际上做了什么。 @JBNizet 我完全重新发布了我的帖子并添加了更多信息。如果有人需要更多信息,请告诉我,我会添加。 【参考方案1】:你不能在两边都设置 inverse="false"。 Hibernate 不能将两个集合(Item 中的用户和 User 中的项目)保存在同一个表中,除非其中一个被称为“反向”,并且可以在写入时忽略。只有在阅读时才会被填满。
我会在 Item 一侧设置 inverse="true"。
然后你必须先保存项目,然后将它们添加到用户,然后保存用户。
【讨论】:
以上是关于Java Hibernate 级联问题的主要内容,如果未能解决你的问题,请参考以下文章