我正在开发一个项目,要求我们能够修改ORM实体上的数据,但不能将其持久保存回数据库。本质上,我们需要修改对象并将其传递给对数据执行某些计算的服务,然后结束请求,而实际上没有任何数据被持久化。问题在于执行计算的服务 需要保留一些数据(运行日志,计算结果)。这意味着我们不能只在流程完成后清除整个会话。
我们正在使用的实体相对复杂(至少十几个关系和更多简单的属性),因此在刷新之前从会话中驱逐实体及其所有相关实体并不是最佳选择。为了使事情变得更加困难,服务中的一些ormFlush()
调用执行计算,这使得手动驱逐实体几乎是不可能的。由于存在大量关系,所以在我们将其发送到服务之前,急切地预先加载所有内容并将其全部逐出是不可行的。
由于这些问题,我试图打开永远不会被刷新的第二个Hibernate会话(基本上是一个沙盒)。我们可以加载实体并在该会话中进行所需的任何更改,而无需担心数据库中存在的更改。
到目前为止它已经成功但有一个例外:我无法在实体上调用隐式的“has”方法(例如hasFoo()
,hasBar()
) - 它会导致NullPointerException。 / p>
示例代码:
ormSession = ormGetSessionFactory().openSession();
person = ormSession.load( "person", javaCast( "int", 123 ) );
// assume person has a o2m relationship for "brother"
writeOutput( person.hasBrother() );
这会导致以下异常:
java.lang.NullPointerException at
coldfusion.orm.ImplicitRelationUDF.runHasMethodWithNoArgs(ImplicitRelationUDF.java:410) at
coldfusion.orm.ImplicitRelationUDF.invoke(ImplicitRelationUDF.java:246) at
coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:431) at
coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:414) at
coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2432) at
cfsean2ecfm1294924799.runPage(C:\websites\test.cfm:11)
我的预感是ImplicitRelationUDF.java正在尝试使用“标准”CF Hibernate会话并且失败,因为这个实体被加载到不同的会话中,但我不知道如何进一步研究。
我采取了另一种仍然不起作用的方法,但它(可能)是值得深思的。它抛出与上面代码相同的错误。
transaction {
person = entityLoadByPK( "person", 123 );
transaction action="rollback";
}
writeOutput( person.hasBrother() );
我愿意解决具体问题(修复有*)或修改实体的更一般问题,并确保数据不会持久存回数据库。
答案 0 :(得分:2)
将会话默认设置为只读
ormSession = ormGetSessionFactory().openSession();
ormSession.setDefaultReadOnly( true );
person = ormSession.load( "person", javaCast( "int", 123 ) );
您在会话中调用的任何内容都是只读的
答案 1 :(得分:0)
我知道你正在使用的实体相对复杂,但我现在能想到的就是在其中编写一个克隆方法并将它所拥有的一切克隆到一个不附加到任何会话的新实例中,并使用该克隆实例传递给您需要orm持久性的服务。
可能有更好的解决方案,但如果时间有限,我很确定这会有效。
How do you deep clone a persistent entity in ColdFusion ORM?
我很乐意学习如何使用ORM会话处理这个问题,因为我已经读过它在ColdFusion中没有很好地实现。