Oracle 禁用只读同义词刷新时的Hibernate自动更新

Oracle 禁用只读同义词刷新时的Hibernate自动更新,oracle,hibernate,spring,Oracle,Hibernate,Spring,我有一个表和两个数据库,它们具有相同的表,但其中一个是另一个的符号链接,只允许在此表上读取 我使用Hibernate将表映射到Java,并使用spring根据一些输入条件将实体管理器的数据源设置为两个数据库之一 当我连接到第二个数据库时,我调用only read only operations(selects),但Hibernate似乎试图将某些内容刷新回数据库,但它无法告知此视图上不允许更新 如何仅对第二个数据源禁用此更新,并对第一个数据源保持正常 更新: 查看堆栈跟踪,刷新似乎从这里开始:

我有一个表和两个数据库,它们具有相同的表,但其中一个是另一个的符号链接,只允许在此表上读取

我使用Hibernate将表映射到Java,并使用spring根据一些输入条件将实体管理器的数据源设置为两个数据库之一

当我连接到第二个数据库时,我调用only read only operations(selects),但Hibernate似乎试图将某些内容刷新回数据库,但它无法告知此视图上不允许更新

如何仅对第二个数据源禁用此更新,并对第一个数据源保持正常

更新: 查看堆栈跟踪,刷新似乎从这里开始:

at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027) at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365) at org.hibernate.ejb.AbstractEntityManagerImpl$1.beforeCompletion(AbstractEntityManagerImpl.java:504) ... 55 more 位于org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) 位于org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50) 位于org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027) 位于org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365) 在org.hibernate.ejb.AbstractEntityManagerImpl$1.before完成(AbstractEntityManagerImpl.java:504) ... 55多
这与hibernate.transaction.flush\u before\u completion属性有关吗?我可以为第二个数据源将其设置为false吗?

首先,您需要确定这是DDL还是DML。如果您不知道,那么我建议您设置hibernate.show\u sql=true以捕获有问题的语句

如果是DDL,那么很可能是Hibernate为您更新模式,您希望另外将Hibernate.hbm2ddl.auto设置配置为“update”或“none”,具体取决于您使用的是实际数据库还是符号链接(只读)数据库。您也可以使用“验证”而不是“无”

如果是DML,那么我将首先确定您的代码是否出于某种原因对仍然连接到活动Hibernate会话的实例进行了更改。如果是这样,那么后续读取可能会导致刷新这些更改,而不会显式保存对象(Grails?)。如果是这种情况,请考虑退出导致刷新的实例(或改用传输对象)

您是否正在使用任何方面或Hibernate生命周期事件来提供对对象的审核?这也可能导致只读访问导致运行插入或更新


结果可能是,如果字段的可更新性发挥作用,您需要为有问题的类提供替代映射,但代码正在完全按照您的意愿执行所有操作(这不太可能;0)。如果您处在一个全注释的世界中,这可能很棘手。如果使用hbm.xml,那么提供替代映射就更容易了。

您的实体很可能在从数据库加载的同一时刻变得“脏”,Hibernate认为它需要存储更改。如果访问器(get和set方法)没有返回与Hibernate设置的值或引用完全相同的值或引用,就会发生这种情况

在我们的代码中,列表发生了这种情况,开发人员创建了新的列表实例,因为他们不喜欢setter中的类型

如果不想更改代码,请将映射更改为field access


您还可以通过在会话中将FlushMode设置为never来防止Hibernate存储更改,但这只会隐藏在其他情况下仍会发生的真正问题,并会导致不必要的更新。

这不是DDL,它只发出DML,我只使用注释,不使用hbm.xml。查看stacktrace,更新似乎是因为以下原因启动的:org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365)上的375400,org.hibernate.ejb.AbstractEntityManagerImpl$1。在完成之前(AbstractEntityManagerImpl.java:504)375402。。。55这是否与hibernate.transaction.flush\u before\u completion设置有关?