使用CF-ORM在ColdFusion 9中需要注意的事项

时间:2010-03-19 20:24:52

标签: orm coldfusion coldfusion-9

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

4 个答案:

答案 0 :(得分:49)

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

    A bug regarding this limitation has been filed in the Adobe Bugbase.

  • 带有ORMReload()
  • ormsettings.dbcreate = "drop create"可能不会删除所有表格。 CF9 Cumulative Hot Fix 1对此进行了一些改进,但您可能希望自己删除数据库中的表。

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

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

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

  • 如果fieldtype="id"和生成器设置为某个生成器,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,通常在“一对多”方面。

  • NOT 在单向关系中使用inverse="true"!这种关系可能根本不存在!

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

  • EntityLoad("entity", 1, true)有效,但EntityLoadByPK("entity", 1)更清洁!

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

  • 如果默认情况下找不到实体,
  • ORMExecuteQuery将返回空数组。

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

  • addDogs(Dog dogs)将加载所有延迟加载属性。或者,您可以尝试<cfdump>或设置top = 1来有效地转储。

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

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

  • 每当cascade="all-delete-orphan"设置required="true",对于使用CFCExplorer浏览CFC的其他人来说更具可读性

  • notnull="true"的效率略高于EntityNew('Y'),如果某个Adobe工程师稍后要保留该实体的话。

  • 由于未修复的Hibernate错误,与继承实体的关系有时可能会中断,请使用new com.X.Y作为解决方法。

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

  • 双向多对多不能使用struct

  • 向struct添加新实体时,当CF持久保存父实体时,将忽略structKeyColumn

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

  • structKeyColumn,实体hibernate会话不再可用,因此将默认忽略postInsert()的设置属性,或者抛出Session is Closed异常。

  • 实体由postInsert()或来自数据库的HQL加载后,即使未调用entityLoad(),更改也会自动保留。

  • 与CF-ORM的交易以一种新的会话开始实施,并在完成时关闭。

  • 事件内部的
  • (即preLoad()/ postInsert()),分配给变量可能会抛出关于类型的Java异常。使用JavaCast()来解决这个bug。

<强>更新

  • CF9.0.1 +:使用EntitySave(),更容易做<cfquery dbtype="hql">,调试输出实际上会显示绑定值。

答案 1 :(得分:7)

添加建议:

  • 关闭ormsettings.flushAtRequestEnd = false,以便在请求结束时没有自动刷新。而是围绕所有写入事务(entitySave()或编辑持久化实体时使用事务(从CF9.01开始,cftransaction为会话完成刷新会话)。
  • 在HQL中使用绑定参数防止SQL注入 - 未命名'?'或命名为':'的符号,以确保ORM对相关字段的类型绑定(如CFQUERYPARAM一样)。防止SQL注入!
  • CF9.0.1允许CFQUERY dbtype =“hql”写入&amp;输出HQL内联。使用CFQUERYPARAM绑定内联params(相当于HQL中未命名的?表示法)。
  • 在HQL中使用LEFT OUTER JOIN FETCH来获取渴望的获取关系。
  • 使用双向关系覆盖CFC上的添加/删除功能,以确保在任何一方都设置双方。
  • 转动ormsettings.logsql = true以在控制台中查看派生SQL。调整log4j休眠设置以进一步调整Hibernate的日志设置。
  • 加入Google群组cf-orm-dev。那里有光明的人。

答案 2 :(得分:2)

在摆弄Hibernate日志记录的同时,您还可以关闭数据源的“维护连接”。

使用SQL Server 2005,您可以启动探查器并观察即将到来的查询。

由于维护连接已关闭,Hibernate每次都会被强制创建新的预准备语句。

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

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

的内容

sp_execute 15,'someparam'

在此之前,运行了sp_prepexec,这是15来自的地方。

答案 3 :(得分:1)

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

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

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