Hibernate多对多单向无需重复

时间:2015-01-04 20:37:17

标签: java hibernate duplicates many-to-many

是否可以在休眠中使用单向多对多映射,以便“子”的副本不会被保存?我正在使用XML映射而不是注释,因为这就是我刚开始的时候。

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

在我的情况下,我用jaxb解组XML来获取java对象,我不需要双向映射。

我有一个Class Article(Item),它有一个Category类,而Category类没有引用回Article。 我想要做的是保存文章对象,只有在类别表中不存在时才将类别插入。类别链接到文章的方式是通过链接表。

我想让它在没有编码的情况下工作的原因是我想学习一些新的东西(休眠)。也许我对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>   

它几乎按照我的意愿工作,只是它在Category表中多次保存相同的类别,这似乎是不必要的。

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

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

当保存第二篇文章(Item)时,我希望hibernate在连接表中将一个条目添加到现有的Economy行,而不是创建一个新的。

我已经尝试使类别唯一,但后来我从hibernate得到sql错误,索引已经包含密钥。

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

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

这删除了我希望避免数据复制的连接表。现在类别或标签出现在类别表中的次数与所有项目(文章)中出现的次数相同。

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

更新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:具有相同标识符值的其他对象已与会话关联

1 个答案:

答案 0 :(得分:0)

因此,如果您的类别只有一个属性,则可以执行此操作:

@Id private String category;

你也可以拥有JPA

@ElementCollection private Set<String> categories;

对于集合中的重复子项:

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

  • 您可以覆盖Category实体的equals / hashcode。但要小心,在覆盖之前必须检查JPA规范。

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