使用多个Java应用程序保持Hibernate数据库完整性

4
我们有两个Java Web应用程序,都是读/写的,并且有三个独立的Java读/写应用程序(一个通过电子邮件加载问题,一个处理XML提要,一个向订阅者发送电子邮件),所有这些应用程序都使用Hibernate并共享一个公共代码库。
我们最近遇到的问题是,通过电子邮件加载的问题有时会覆盖在其中一个Web应用程序中创建的问题。请注意,这些是应该具有不同ID的单独的问题。我们最初认为这是缓存问题。我们已尝试关闭二级缓存,但这没有任何区别。
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.cache.use_second_level_cache">false</property>

问题:


@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
@DocumentId
public Integer getId() {
    return this.id;
}

我们顺便提一下,我们正在使用MySQL。
CREATE TABLE  `question` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  ...
  PRIMARY KEY (`id`),
  ...
) ENGINE=InnoDB DEFAULT CHARSET=utf8

我们不会明确地打开和关闭会话,而是让Hibernate通过Util.getSessionFactory().getCurrentSession()来管理它们。
我们不想在这个阶段设置一个集群化的第二级缓存,因为这会增加另一层复杂性,而我们对整个应用程序的性能水平非常满意。
那么,在Web应用程序中实现open-session-in-view模式并在独立应用程序中手动管理会话听起来是否可以解决这个问题?
或者还有其他建议/想法吗?

问题是如何确定的(还有主键是什么),邮件和网页更新是否针对同一个问题? - mmmmmm
听起来好像是应用程序生成主键,而不是使用由数据库处理的序列。 - khmarbaise
嗨,我刚刚更新了我的问题,并为您提供了更多信息。我认为IDENTITY策略会导致MySQL生成ID? - Austen
2个回答

3
由于所有问题都有ID,我假设所有问题都是从您的MySQL数据库中获取的。
假设您不需要将问题存储为内存中的透明对象,而是每次呈现它们时都选择所有问题,我有一个简单的建议。
用数据库中的序列替换ID生成器(最终在MySql中作为自动编号)。然后,数据库而不是应用程序保证每个问题都获得唯一的ID。
这个解决方案非常简单,可以降低复杂度。只有当您将来自不同来源的所有传入问题持久化到数据库中,然后从此处选择它们时,它才能正常工作。
如果此解决方案导致性能问题,则应更多地了解您的Hibernate ID生成器的工作方式。Hibernate为不同的场景提供了几种不同的生成器。
希望这可以帮助您!

我已经添加了问题模式。所以您是在暗示我们移除@GeneratedValue(strategy = IDENTITY)注释吗? - Austen
是的,我这么做。如果多个应用程序向同一张表中插入值,则表上的插入触发器是最可靠的解决方案。该触发器应该从序列中设置ID。 - Espen
如果我删除@GeneratedValue注解,那么会出现以下错误:org.hibernate.id.IdentifierGenerationException: 必须在调用save()之前手动分配此类的ids: 你是在建议我手动从数据库中直接找到id,然后手动分配给新的问题吗? - Austen
1
据我的理解,GenerationType.IDENTITY与MySQL自动增量正确配合使用。请参考:https://dev59.com/q3RB5IYBdhLWcg3wkIBN - Austen
你可以在构造函数中或字段的默认值中将id字段设置为-1。这样,你就可以很容易地看到你的数据库触发器是否起作用了。 - Espen

0
原来这个问题根本与Hibernate无关。
暂存服务器上的一个数据库表填满了应该被清理的旧数据。这最初给人的印象是id被覆盖,但进一步调查证明不是这样的!
一旦我们删除了有问题的数据,一切都好了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接