我在ChatComponent和它的聊天消息之间编写了一个非常基本且天真的oneToMany关系,如下所示:
@OneToMany
List<ChatMessage> chatMessages;
这基本上有效,即做类似的事情:
ChatMessage chatMessage = vo.toDomainObject();
chatMessage.setDate(new Date());
//Add the message to the chat component
em.getTransaction().begin();
em.persist(chatMessage);
chat.addChatMessage(chatMessage);
em.persist(chat);
em.getTransaction().commit();
完成工作。只看着SQL日志,我可以看到,每次聊天消息的整个集合都会再次存在。这显然是我买不起的东西,因为聊天消息很快就会成千上万。
每个聊天消息重复的SQL如下:
Hibernate: insert into BaseComponent_ChatMessage (BaseComponent_id, chatMessages_id) values (?, ?)
之前是:
Hibernate: delete from BaseComponent_ChatMessage where BaseComponent_id=?
由此我得出结论,Hibernate没有办法知道我们没有处理一整套新对象,而且它应该保留已有的对象。
我确信有一种方法可以添加(和持久)只有关系中许多方面的一个成员,但我似乎无法找到方法。
答案 0 :(得分:2)
我发现每次避免整个聊天消息列表的唯一方法是在聊天组件和聊天消息之间建立双向关系
@OneToMany(cascade={CascadeType.PERSIST,CascadeType.MERGE}, fetch=FetchType.LAZY, mappedBy="parent")
List<ChatMessage> chatMessages;
@ManyToOne
@JoinColumn(name="OWNER_CHAT_COMPONENT_ID", nullable=false)
private ChatComponent parent;
然后在addChatMessage函数中,我可以简单地向聊天组件添加一条消息,而不必保留它,然后保持聊天组件并且效果很好。
em.getTransaction().begin();
chat.addChatMessage(chatMessage);
em.persist(chat);
em.getTransaction().commit();
答案 1 :(得分:1)
覆盖hashCode
类的equals
和ChatMessage
方法,以便Hibernate知道这些是相同的对象。
使用IDE生成hashCode()和equals()。在Eclipse中,右键单击&gt;来源&gt;生成hashCode和equals,并为您的实体选择@Id
的属性。
另外,请尝试将cascade=CascadeType.ALL
属性添加到@OneToMany