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

发布于 2024-08-25 10:30:57 字数 61 浏览 4 评论 0原文

您在带有 CF-ORM (Hibernate) 的 ColdFusion 9 中观察到了哪些应该注意的事情?

What are some of the things you've observed in ColdFusion 9 with CF-ORM (Hibernate) that one should watch out for?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

陈独秀 2024-09-01 10:30:57
  • entity init() 方法不得包含必需的参数,否则 EntityNew() 和其他 CF-ORM 操作将中断。您可能想要使用工厂来创建实体,并在其中强制执行所需的参数。

    有关此限制的错误已在 Adob​​e Bugbase 中提交。< /a>

  • ORMReload()ormsettings.dbcreate = "drop create" 可能不会为您删除所有表。 CF9 Cumulative Hot Fix 1 稍微改进了这一点,但您可能想要放弃自己在数据库中的表。

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

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

  • type="numeric" 默认为 <代码>浮点,而不是<代码>整数。如果需要,请使用 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,通常是在“一对多”方面。

  • 不要在单向关系中使用inverse="true"!该关系可能根本不会持久!

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

  • EntityLoad("entity", 1, true) 有效,但 EntityLoadByPK("entity", 1) 更干净!

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

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

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

  • 将加载所有延迟加载属性。或者,您可以尝试 或设置 top=1 以高效转储。

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

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

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

  • EntityNew('Y') 效率比new com.XY 如果根据某些 Adob​​e 工程师的说法,实体稍后要保留。

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

    由于未修复的

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

  • 双向多对多不能使用struct

  • 向struct添加新实体时,structKeyColumn会被忽略CF 保留父实体。

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

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

  • 通过entityLoad()或HQL从数据库加载实体后,即使不调用EntitySave(),更改也会自动保留。

  • CF-ORM 事务的实现方式

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

更新

  • CF9.0.1+:使用,更容易做到cfqueryparam,并且调试输出实际上向您显示绑定值。
  • entity init() method must not have required argument(s), otherwise EntityNew() and other CF-ORM actions will break. You may want to use a Factory to create the entity, and enforce the required arguments there.

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

  • ORMReload() with ormsettings.dbcreate = "drop create" might not drop all tables for you. CF9 Cumulative Hot Fix 1 improves this a little bit, but you might want to drop the tables in DB yourself.

  • type="date" (default to use ormtype="date"), will only store date but not time. If you want to persisted time as well, use ormtype="timestamp"

  • type="string" will default to varchar(255)

  • type="numeric" will default to float, not int. Use ormtype="int" if needed.

  • if fieldtype="id" and generator is set to some generator, ormtype will default to int.

  • type="string" length="10" will use varchar(10), not char(10)

  • ormtype="char" length="10" will use char(1) still. Use sqltype="char(10)" if you really need to.

  • type="boolean" use tinyint by default, use sqltype="bit" if you need to.

  • should use inverse=true in a bi-directional relationship, usually in "one-to-many" side.

  • do NOT use inverse="true" in uni-directional relationship! The relationship might not be persisted at all!

  • If you use MS-SQL, you cannot have more than 1 entity with one-to-one property set to Null, because Null is considered as an unique value in an index. Good idea to make column not null. (or use linktable)

  • EntityLoad("entity", 1, true) works, but EntityLoadByPK("entity", 1) is cleaner!

  • EntityLoad(), EntityLoadByPK(), and ORMExecuteQuery with unique=true, will return null if entity is not found. Use isNull() to check before you use the returned value.

  • ORMExecuteQuery will return empty array if no entity is found by default.

  • don't forget to use singularname property in "one-to-many" / "many-to-many" for nicer looking generated functions (e.g. addDog(Dog dog) vs addDogs(Dog dogs) .)

  • <cfdump> will load all the lazy-load properties. Alternatively you may try <cfdump var="#entityToQuery([entity])#"> or set top=1 to dump efficiently.

  • entity stored in Session scope will be disconnected with its Hibernate session scope, and lazy load property will not be loaded. To restore the hibernate session scope, use entityLoadByExample() or entitySave(entity).

  • cascade="all-delete-orphan" usually make more sense for "one-to-many" or "many-to-many" relationship. Hibernate sets null then delete, so make sure the column is nullable. Test and see if that's your desire behaviour.

  • set required="true" whenever notnull="true", more readable for others browsing the CFC with CFCExplorer

  • EntityNew('Y') is slightly more efficient than new com.X.Y if the entity is to be persisted later according to some Adobe engineer.

  • relationship with an inherited entity may break sometimes due to an unfixed Hibernate bug, use linktable as a workaround.

  • structKeyColumn cannot be the PK of the target entity.

  • bi-directional many-to-many cannot use struct

  • When adding new entity to struct, structKeyColumn is ignored when CF persists the parent entity.

  • If you access the one-to-many / many-to-many array or struct directly, make sure the corresponding array/struct exists before use. Generated addX()/hasX()/removeX() are safe to use anytime.

  • at postInsert(), the entity hibernate session is no longer available, so setting property at postInsert() will be silently ignore, or Session is Closed exception will be thrown.

  • after entity is loaded by entityLoad() or HQL from DB, the changes will be automatically persisted even if EntitySave() is not called.

  • transaction with CF-ORM is implemented in a way that it starts a new session and close when it's done.

  • inside the event (i.e. preLoad() / postInsert()), assigning to variables might throw Java exception about types. Use JavaCast() to work around the bug.

UPDATE

  • CF9.0.1+: use <cfquery dbtype="hql">, easier to do cfqueryparam, and debug output actually shows you the binded values.
煮酒 2024-09-01 10:30:57

添加建议:

  • 关闭 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。那里的人很聪明。

Add'l recommendations:

  • Turn off ormsettings.flushAtRequestEnd = false to not have auto-flush at the end of the request. Instead use transactions (as of CF9.01, cftransaction flushes session for you transaction completion) around all write transactions (entitySave() or when you edit a persisted entity).
  • Prevent SQL injection by using binded parameters in HQL - unnamed '?' or named ':' notations, to assure type binding by ORM against the field in question (like CFQUERYPARAM does). Prevent SQL injection!
  • CF9.0.1 allows CFQUERY dbtype="hql" to write & output HQL inline. Use CFQUERYPARAM to bind params inline (equivalent to unnamed ? notation in HQL).
  • Use LEFT OUTER JOIN FETCH in HQL to eager fetch relationships.
  • Override add/remove functions on CFCs with bi-directional relationships to assure both sides are set when either is.
  • Turn ormsettings.logsql=true to view derived SQL in the console. Adjust log4j Hibernate settings to further tweak log settings from Hibernate.
  • Join Google Group cf-orm-dev. Bright people there.
少女七分熟 2024-09-01 10:30:57

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

使用 SQL Server 2005,您可以启动探查器并观察正在进行的查询。

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

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

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

sp_execute 15, 'someparam' 的

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

In conjunction with fiddling with the Hibernate logging you can also turn "maintain connections" off for your datasource.

With SQL Server 2005 you can then launch profiler and watch the queries coming thru.

Since maintain connections is off Hibernate will be forced to create new prepared statements each time.

Reading prepared statements can be tough, but at least you can see the raw queries that are being generated.

If you maintain connections these prepared statements are created once and you just see something like

sp_execute 15, 'someparam'

Before this was ran sp_prepexec was ran which is where the 15 comes from.

逆夏时光 2024-09-01 10:30:57

EntityReload 似乎会忽略 CFDUMP 等延迟加载。

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

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

EntityReload appears to ignore lazy loading like CFDUMP.

I use it after an EntitySave to grab any defaulted columns in the db. I see in SQL Profiler ( a tracing tool for SQL Server ) lots of queries coming thru.

If change it to a EntityLoadByPK, etc it will load up the object and will not see all the excess relationship queries which for me can cause major problems.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文