27

您在使用 CF-ORM (Hibernate) 的 ColdFusion 9 中观察到的哪些事情需要注意?

4

4 回答 4

50
  • 实体init()方法不能有必需的参数,否则EntityNew()其他 CF-ORM 操作将中断。您可能希望使用工厂来创建实体,并在那里强制执行所需的参数。

    Adobe Bugbase 中已提交有关此限制的错误。

  • ORMReload()withormsettings.dbcreate = "drop create"可能不会为您删除所有表格。 CF9 Cumulative Hot Fix 1稍微改进了这一点,但您可能希望自己删除 DB 中的表。

  • type="date"(默认使用ormtype="date"),将只存储日期而不存储时间。如果您还想保持时间,请使用ormtype="timestamp"

  • type="string"将默认为varchar(255)

  • type="numeric"将默认为float,而不是int。如果需要,请使用 ormtype="int"。

  • 如果fieldtype="id"和 generator 设置为某个生成器,ormtype 将默认为int.

  • type="string" length="10"会用varchar(10),不会char(10)

  • ormtype="char" length="10"仍将使用char(1)sqltype="char(10)"如果您确实需要,请使用。

  • type="boolean"tinyint默认使用,sqltype="bit"需要时使用。

  • 应该inverse=true在双向关系中使用,通常在“一对多”方面。

  • 不要在单向关系中使用inverse="true"!这段关系可能根本就不会维持下去!

  • 如果您使用 MS-SQL,则不能有超过 1 个将一对一属性设置为 Null 的实体,因为 Null 被视为索引中的唯一值。使列不为空的好主意。(或使用链接表)

  • EntityLoad("entity", 1, true)工作,但EntityLoadByPK("entity", 1)更清洁!

  • EntityLoad(), EntityLoadByPK(), 和ORMExecuteQuery,如果找不到实体unique=true,将返回。null用于在使用isNull()返回值之前进行检查。

  • ORMExecuteQuery如果默认没有找到实体,将返回空数组。

  • 不要忘记singularname在“一对多”/“多对多”中使用属性以获得更好看的生成函数(例如addDog(Dog dog)vs addDogs(Dog dogs).)

  • <cfdump>将加载所有延迟加载属性。或者,您可以尝试<cfdump var="#entityToQuery([entity])#">或设置 top=1 以有效转储。

  • 存储在 Session 范围内的实体将与其 Hibernate 会话范围断开连接,并且不会加载延迟加载属性。要恢复休眠会话范围,请使用entityLoadByExample()entitySave(entity)

  • cascade="all-delete-orphan"通常对“一对多”或“多对多”关系更有意义。Hibernate 设置 null 然后删除,因此请确保该列可以为空。测试并查看这是否是您的愿望行为。

  • required="true"随时设置notnull="true",对于使用 CFCExplorer 浏览 CFC 的其他人来说更具可读性

  • EntityNew('Y')new com.X.Y根据某些 Adob​​e 工程师的说法,如果实体稍后被持久化,它的效率会稍高一些。

  • 由于未修复的 Hibernate 错误,与继承实体的关系有时可能会中断,linktable用作解决方法。

  • structKeyColumn不能是目标实体的PK。

  • 双向多对多不能使用struct

  • 将新实体添加到结构时,structKeyColumn当 CF 保留父实体时将被忽略。

  • 如果直接访问一对多/多对多数组或结构体,使用前请确保对应的数组/结构体存在。生成的 addX()/hasX()/removeX() 可以随时安全使用。

  • postInsert(),实体休眠会话不再可用,因此在 postInsert() 设置属性将被静默忽略,否则将抛出 Session is Closed 异常。

  • 在实体被entityLoad()DB 或 HQL 加载后,即使EntitySave()没有调用,更改也会自动持久化。

  • CF-ORM 的事务以启动新会话并在完成后关闭的方式实现。

  • 在事件内部(即 preLoad() / postInsert()),分配给变量可能会引发关于类型的 Java 异常。使用 JavaCast() 来解决该错误。

更新

  • CF9.0.1+:使用<cfquery dbtype="hql">,更容易做cfqueryparam,调试输出实际上显示了绑定的值。
于 2010-03-19T20:40:14.457 回答
7

添加建议:

  • 关闭 ormsettings.flushAtRequestEnd = false 以在请求结束时不自动刷新。而是在所有写入事务(entitySave() 或编辑持久化实体时)使用事务(从 CF9.01 开始,cftransaction 刷新会话以完成事务)。
  • 通过在 HQL 中使用绑定参数来防止 SQL 注入 - 未命名的“?” 或命名为 ':' 符号,以确保 ORM 对相关字段的类型绑定(就像 CFQUERYPARAM 一样)。防止SQL注入!
  • CF9.0.1 允许 CFQUERY dbtype="hql" 内联写入和输出 HQL。使用 CFQUERYPARAM 绑定内联参数(相当于 HQL 中的未命名 ? 表示法)。
  • 在 HQL 中使用 LEFT OUTER JOIN FETCH 来急切获取关系。
  • 覆盖具有双向关系的 CFC 上的添加/删除功能,以确保双方都已设置。
  • 打开 ormsettings.logsql=true 在控制台中查看派生的 SQL。调整 log4j Hibernate 设置以进一步调整来自 Hibernate 的日志设置。
  • 加入 Google 群组 cf-orm-dev。那里的人很聪明。
于 2010-08-09T02:29:31.523 回答
2

结合使用 Hibernate 日志记录,您还可以为您的数据源关闭“维护连接”。

使用 SQL Server 2005,您可以启动探查器并观察通过的查询。

由于保持连接关闭,Hibernate 将被迫每次创建新的准备好的语句。

阅读准备好的语句可能很困难,但至少您可以看到正在生成的原始查询。

如果您保持连接,这些准备好的语句会创建一次,您只会看到类似

sp_execute 15, 'someparam'

在此之前运行 sp_prepexec 是 15 的来源。

于 2010-10-29T04:23:15.343 回答
1

EntityReload 似乎忽略了像 CFDUMP 这样的延迟加载。

我在 EntitySave 之后使用它来获取数据库中的任何默认列。我在 SQL Profiler(SQL Server 的跟踪工具)中看到了很多查询。

如果将其更改为 EntityLoadByPK 等,它将加载对象并且不会看到所有多余的关系查询,这对我来说可能会导致重大问题。

于 2010-04-30T18:24:30.837 回答