Каковы некоторые из вещей, которые вы наблюдали в ColdFusion 9 с CF-ORM (Hibernate), за которыми следует следить?
Что следует учитывать в ColdFusion 9 с CF-ORM
Ответ 1
-
объект
init()
метод не должен иметь необходимых аргументов, иначеEntityNew()
и другие действия CF-ORM будут разбиты. Вы можете использовать Factory для создания сущности и принудительно использовать необходимые аргументы.Ошибка в отношении этого ограничения была подана в 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", если необходимо. -
if
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
в двунаправленном соотношении, обычно со стороны "один ко многим". -
do НЕ использовать
inverse="true"
в однонаправленных отношениях! Отношения могут не сохраняться вообще! -
Если вы используете MS-SQL, у вас не может быть более одного объекта с индивидуальным свойством, равным Null, потому что Null считается уникальным значением в индексе. Хорошая идея сделать столбец не нулевым. (или используйте ссылку)
-
EntityLoad("entity", 1, true)
работает, ноEntityLoadByPK("entity", 1)
чище! -
EntityLoad()
,EntityLoadByPK()
иORMExecuteQuery
сunique=true
, вернетnull
, если объект не найден. ИспользуйтеisNull()
для проверки перед использованием возвращаемого значения. -
ORMExecuteQuery
возвращает пустой массив, если по умолчанию не найдено ни одного объекта. -
не забывайте использовать свойство
singularname
в "один-ко-многим" / "много-ко-многим" для более приятных сгенерированных функций (например,addDog(Dog dog)
vsaddDogs(Dog dogs)
.) -
<cfdump>
загрузит все свойства ленивой нагрузки. В качестве альтернативы вы можете попробовать<cfdump var="#entityToQuery([entity])#">
или установить top = 1 для эффективной сбрасывания. -
объект, хранящийся в области сеанса связи, будет отключен с помощью области сеанса Hibernate, а свойство lazy load не будет загружено. Чтобы восстановить область сеанса спящего режима, используйте
entityLoadByExample()
илиentitySave(entity)
. -
cascade="all-delete-orphan"
обычно имеют больше смысла для отношений "один ко многим" или "многие ко многим". Hibernate устанавливает null, а затем удаляет, поэтому убедитесь, что столбец имеет значение NULL. Протестируйте и посмотрите, есть ли это ваше желание. -
установить
required="true"
всякий раз, когдаnotnull="true"
, более читаемый для других, просматривающих CFC с CFCExplorer -
EntityNew('Y')
немного эффективнее, чемnew com.X.Y
, если объект должен быть сохранен позже в соответствии с некоторыми инженерами Adobe. -
связь с унаследованным объектом может иногда нарушаться из-за неподключенной ошибки Hibernate, используйте
linktable
как обходной путь. -
structKeyColumn
не может быть PK целевого объекта. -
двунаправленные многие-ко-многим не могут использовать struct
-
При добавлении нового объекта в структуру
structKeyColumn
игнорируется, когда CF сохраняется в родительском объекте. -
Если вы обращаетесь к массиву или структуре "один ко многим/много-ко-многим", убедитесь, что соответствующий массив/структура существует до использования. Сгенерированный addX()/hasX()/removeX() безопасен для использования в любое время.
-
at
postInsert()
сеанс hibernate сущности больше не доступен, поэтому установка свойства в postInsert() будет игнорироваться молча или исключение Session is Closed. -
после того, как объект загружается
EntityLoad()
или HQL из БД, изменения будут сохраняться автоматически, даже еслиEntitySave()
не вызывается. -
транзакция с CF-ORM реализована таким образом, что она запускает новый сеанс и закрывается, когда это делается.
-
внутри события (т.е. preLoad()/postInsert()), назначение переменных может вызвать исключение Java для типов. Используйте JavaCast(), чтобы обойти ошибку.
UPDATE
- CF9.0.1 +: используйте
<cfquery dbtype="hql">
, проще сделатьcfqueryparam
, а вывод отладки фактически показывает вам привязанные значения.
Ответ 2
Добавить рекомендации:
- Отключите ormsettings.flushAtRequestEnd = false, чтобы не было автоматической очистки в конце запроса. Вместо этого используйте транзакции (по состоянию на CF9.01, cftransaction сбрасывает сеанс для завершения транзакции) вокруг всех транзакций записи (entitySave() или при редактировании сохраняемого объекта).
- Предотвратить SQL-инъекцию с помощью связанных параметров в HQL - неназванный '?' или с именем ':', чтобы гарантировать привязку типа ORM к рассматриваемому полю (например, CFQUERYPARAM). Предотвратите SQL-инъекцию!
- CF9.0.1 позволяет CFQUERY dbtype = "hql" записывать и выводить HQL inline. Используйте CFQUERYPARAM для привязки params inline (эквивалент нонменованной нотации в HQL).
- Используйте LEFT OUTER JOIN FETCH в HQL для поиска связей.
- Переопределить функции добавления/удаления на CFC с двунаправленными отношениями для обеспечения того, чтобы обе стороны были установлены, когда они есть.
- Поверните ormsettings.logsql = true, чтобы просмотреть производный SQL в консоли. Отрегулируйте параметры спящего режима log4j для дальнейшей настройки настроек журнала из Hibernate.
- Присоединитесь к группе Google cf-orm-dev. Яркие люди там.
Ответ 3
В сочетании с ведением журнала Hibernate вы также можете отключить "поддерживать соединения" для своего источника данных.
С помощью SQL Server 2005 вы можете запустить профайлер и посмотреть, как идут запросы.
Поскольку поддержка соединений отключена, Hibernate будет вынужден каждый раз создавать новые подготовленные операторы.
Чтение подготовленных заявлений может быть жестким, но по крайней мере вы можете видеть необработанные запросы, которые генерируются.
Если вы поддерживаете соединения, эти подготовленные операторы создаются один раз, и вы просто видите что-то вроде
sp_execute 15, 'someparam'
До того, как это было запущено, запущено sp_prepexec, из которого происходит 15.
Ответ 4
EntityReload, похоже, игнорирует ленивую загрузку, такую как CFDUMP.
Я использую его после EntitySave для захвата столбцов по умолчанию в db. Я вижу в SQL Profiler (инструмент трассировки для SQL Server) много запросов, проходящих через.
Если вы измените его на EntityLoadByPK и т.д., он загрузит объект и не увидит все лишние запросы отношений, которые могут вызвать серьезные проблемы.