【问题标题】:Hibernate many-to-many unidirectional without duplicates休眠多对多单向无重复
【发布时间】:2015-03-02 10:25:23
【问题描述】:

是否可以在休眠中进行单向多对多映射,从而不会保存“子”的重复项?我使用的是 XML 映射而不是注释,因为那是我刚开始的时候。

我只发现这个作为一种潜在的解决方案,但我想知道是否可以在不编码的情况下配置 hibernate: Hibernate cascade many to many creates duplicates in child reference

在我的例子中,我用 jaxb 解组 XML 来获取 java 对象,我不需要双向映射。

我有一个 Article(Item) 类,它有一组 Category,并且 Category 类没有对 Article 的引用。 我想要做的是保存文章对象,如果它们还不存在,则只将类别插入到 Category 表中。类别链接到文章的方式是通过链接表。

我想让它在不编码的情况下工作的原因是我想学习一些新的东西(休眠)。可能是我对Hibernate的认知有误,我以为只要配置对了它就能搞清楚自己需要做什么。 到目前为止,我已经花了将近一天的时间学习 hibernate,但考虑到我本可以自己设计 db 表并在一小时内完成正确插入/更新的代码,感觉效率并不高。

这是一个与我类似的示例,他们保存了 2 名学生,他们都拥有相同的课程。尽管如此,课程仅在课程表中保存一次: http://www.dzone.com/tutorials/java/hibernate/hibernate-example/hibernate-mapping-many-to-many-using-annotations-1.html

这里还有一个示例,但它是双向的,我无法以相同的方式进行逆映射,因为 Category 没有对 Article 的引用: http://viralpatel.net/blogs/hibernate-many-to-many-xml-mapping-example/ (顺便说一下,Viral Patel 有非常好的教程=)

Article has properties:
String Title;
Set<Category> categories;

Category has property:
String category;

到目前为止,在 Item(Article) 映射中,我有这个:

<set name="categories" cascade="save-update" table="ItemCategory"> 
   <key column="itemID"/>
   <many-to-many column="categoryID" class="Category"/>
</set>   

它几乎可以按我的意愿工作,只是它确实在类别表中多次保存相同的类别,这似乎没有必要。

我主要想使用 Hibernate 来避免设计表格并轻松地将我的 RSS 对象转储为结构化格式(如 nosql 数据库)。

更新: 重复项来自添加其他项目(文章)时,这些项目(文章)具有与类别表中已存在的相同类别。 例如。第一项具有经济和政治类别 第二条有经济

保存第二篇文章(项目)后,我希望休眠将连接表中的条目添加到现有经济行,而不是创建新行。

我已经尝试使类别唯一,但随后我从休眠中收到 sql 错误,即索引已包含键。

更新 2: 我将 Item 类更改为具有一组字符串而不是类别。 映射现在看起来像:

<set name="categories" table="Category">
    <key column="itemID"/>
    <element column="category" type="string"/>
</set>  

这将删除我想要避免数据重复的连接表。现在类别或标签出现在类别表中的次数与它们在所有项目(文章)中出现的次数一样多。

整个想法是在存储 1000 个项目时减少数据库中的数据。大多使用相同的类别或标签,因此如果可以使用连接表以使 Category 表仅包含唯一类别,则可以去除大量冗余。

更新 3: 我的问题似乎与此类似: Using saveOrUpdate() in Hibernate creates new records instead of updating existing ones

更新 4: 我切换回在 Item 类中有一组类别,以通过将 Category.category 作为键来测试它是否有效。 项目的映射:

<set name="categories" cascade="save-update" table="ItemCategory"> 
   <key column="itemID"/>
   <many-to-many column="category" class="Category"/>
</set>     

类别的映射:

<id column="category" name="category" unsaved-value="0">
  <generator class="assigned"/>
</id> 

结果是我得到了异常: org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已与会话关联

【问题讨论】:

    标签: java hibernate duplicates many-to-many


    【解决方案1】:

    所以如果你的 Category 只有一个属性,你可以这样做:

    @Id private String category;
    

    你也可以在 JPA 中拥有

    @ElementCollection private Set<String> categories;
    

    对于您集合中的重复孩子:

    在 Java 中,“Set”不能有重复项。

    • 您可以覆盖类别实体的等号/哈希码。但请注意,您必须在覆盖之前检查 JPA 规范。

    • 您可以使用“选择”搜索类别并尝试添加它。类别实体将在您的持久性上下文中,因此它将在您的“Set”中具有相同的指针。如果找不到,请创建一个新类别。

    【讨论】:

    • 我在 xml 映射中找不到元素集合,我发现了这个:stackoverflow.com/questions/25720369/… 我使用 set 实现了它,并且在 Item 类中我将类别集减少为一组字符串。恕我直言,这只是避免了这个问题。我想知道是否可以以不重复类别表中的类别的方式使用连接表以供将来参考。 IE。仅当类别不存在时才插入。
    • 如果您的 ID 是您的类别,则不能重复。 ElementCollection 是 JPA。我猜你在hibernate中有这样的东西。
    猜你喜欢
    • 1970-01-01
    • 2013-04-30
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    相关资源
    最近更新 更多