Infor LN DAL Hooks and User Exit Functions Reference
This reference lists the Infor LN 10.x DAL hooks, user exit hooks and DAL functions a developer uses, with when each fires, what it returns and the trap to avoid. It complements the DAL hook review checklist, which is for code review rather than lookup.
| Hook / function | Type | Fires when | Arguments / return | Typical use | Gotcha |
|---|---|---|---|---|---|
before.save.object(mode) | Object hook | Before a record is inserted or updated through the DAL | mode is DAL_NEW or DAL_UPDATE; return 0 to continue or DALHOOKERROR to reject | Whole-record validation, cross-field rules, blocking a save | Set a message with dal.set.error.message before returning DALHOOKERROR, or the user sees a generic failure |
after.save.object(mode) | Object hook | After the record is written, inside the same transaction | mode is DAL_NEW or DAL_UPDATE; return 0 or DALHOOKERROR | Updating related tables, writing history or log records | Do not commit here; an error rolls back the whole transaction |
before.destroy.object() | Object hook | Before a record is deleted through the DAL | Return 0 or DALHOOKERROR | Blocking deletes of records still in use | Reference checks from the data dictionary run anyway; only add business rules |
after.destroy.object() | Object hook | After the record is deleted, inside the transaction | Return 0 or DALHOOKERROR | Cleaning up dependent custom records | The deleted record values are still in the table buffer, the row is gone from the database |
after.commit.transaction() | Object hook | After the transaction that changed the record is committed | No return value used to reject | Actions that must only happen when data is final, such as notifications | Too late to reject; validation belongs in before hooks |
after.abort.transaction() | Object hook | After the transaction is aborted | No return value used to reject | Resetting variables or caches set in earlier hooks | Database changes are already rolled back |
<field>.check() | Property hook | When the field value is validated (input or save) | Return 0 or DALHOOKERROR with a message | Single field validation, for example a range or status check | Fires for every entry path, including imports and BOD processing |
<field>.is.valid() | Property hook | When LN checks whether the current value is allowed | Return true or false | Restricting allowed values based on other fields | Keep it fast; it can run many times per record |
<field>.is.mandatory() | Property hook | When the UI or DAL needs to know if the field must be filled | Return true or false | Conditionally mandatory fields | Return a value that depends only on the record buffer, not on session variables |
<field>.is.readonly() | Property hook | When the field is displayed or changed | Return true or false | Locking fields after a status change | DAL 1 sessions may still hold the same rule in the UI script; remove duplicates |
<field>.is.applicable() | Property hook | When LN checks if the field applies to the record | Return true or false | Hiding fields that make no sense for the record type | A non-applicable field is not validated, so do not rely on its check hook |
<field>.is.derived() | Property hook | When LN checks if the value is calculated rather than entered | Return true or false | Fields filled from other fields | Pair it with an update hook that actually sets the value |
<field>.default.value() | Property hook | When a new record is initialised | Sets the field in the record buffer | Defaults on create | Defaults are not reapplied on update |
<field>.update() | Property hook | When a field it depends on changes | Sets the field in the record buffer | Recalculating a field after a related field changes | Avoid circular updates between two fields |
Business method hooks | DAL 2 hook | When the UI decides whether a business method form command is enabled or visible | Enable, disable or hide the command | Hiding actions that do not apply to the record status | Only in DAL 2 scripts, which exist for tables used in business objects |
ue.after.before.save.object(mode) | User exit hook | After the standard before.save.object hook has run | Same mode argument; return 0 or DALHOOKERROR | Customer validation on save without changing the standard DAL | Lives in the UE DLL, so it survives standard DAL updates, but test it after every solution |
ue.after.after.destroy.object() | User exit hook | After the standard after.destroy.object hook has run | Return 0 or DALHOOKERROR | Deleting or flagging customer tables linked to the deleted record | Keep it short; it runs inside the delete transaction |
UE DLL | Location | - | A separate user exit library per table, maintained like other libraries in ttadv2530m000 | Finding or creating the user exit library for a table | Check the exact library naming rule in the Programmer's Guide for your Enterprise Server version before you create one |
DALHOOKERROR | Return constant | - | Returned by a hook to signal failure | Rejecting a save, delete or field value | Always set the message first |
DAL_NEW / DAL_UPDATE | Mode constants | - | Values of mode in save hooks | Different rules for insert and update | Test both paths; many bugs only appear on update |
dal.set.error.message(msg_code, args) | DAL function | Called in a hook before returning DALHOOKERROR | Message code plus optional arguments | Returning a translatable error to the caller | Use a message code, not hard coded text, so it works in every language |
dal.get.error.message() | DAL function | Called after a DAL call failed | Returns the error message set by the DAL | Showing or logging why a save failed | Read it straight after the failing call |
dal.new.object(table) | DAL function | Called from a script to start a new record through the DAL | Table name; return 0 or an error | Creating records so all DAL rules run | Direct db.insert skips the DAL hooks |
dal.change.object(table) | DAL function | Called to start an update of the current record | Table name; return 0 or an error | Updating through the DAL | Select the record for update first |
dal.set.field(field, value) | DAL function | Called between dal.new.object or dal.change.object and dal.save.object | Field name and value | Setting values so property hooks run | Assigning the table field directly skips the field hooks |
dal.save.object(table) / dal.destroy.object(table) | DAL function | Called to save or delete through the DAL | Table name; return 0 or an error | Running the object hooks from code | Check the return value and commit only when it is 0 |
DAL 1 script | Location | - | Maintained in Program Scripts / Libraries (ttadv2530m000) | Database logic and integrity rules per table, introduced in Baan 5.0 | Business logic may still be split with the UI script |
DAL 2 script | Location | - | Maintained in Program Scripts / Libraries (ttadv2530m000) | All business logic for a table used in a business object | Logic runs for BOL and Business Adapter access too |
Compile | Location | - | Compile Program Scripts / Libraries (ttadv2230m000) | Compiling DAL and UE libraries in your VRC | Only the latest script in the VRC tree is compiled |
Hook and function names follow the Data Access Layer chapter of the Infor ES Programmer's Guide and the LN Tools online help. Signatures can differ slightly by Enterprise Server version, so check the guide for your tools release before you copy a signature.
Get a DAL or user exit reviewed
Send us a DAL or UE script and the rule it should enforce, and we will review hook choice, error handling and upgrade safety.
Optional. The tool and every export work without this. No spam.
How to use it
Search for the hook you are about to write, for example before.save.object, and read the Fires when and Gotcha columns before coding. Filter by type to see all property hooks when you design field behaviour, or all DAL functions when you write a script that creates or updates records. The table is a quick lookup; the authoritative signatures are in the Data Access Layer chapter of the Infor ES Programmer's Guide for your Enterprise Server version.
Where this lives in LN
A DAL is a dynamic link library linked to one LN table. DAL 1 scripts arrived with Baan 5.0 and hold database logic such as integrity rules; object hooks replaced the old main.table.io sections. DAL 2 scripts hold all business logic for tables used in predefined business objects, so the logic runs automatically when another application reaches the table through the BOL or Business Adapter. Both are edited in Program Scripts / Libraries (ttadv2530m000) and compiled with ttadv2230m000. User exits live in a separate user exit library for the table, so they are kept apart from the standard DAL.
Worked example: blocking a save
Rule: a sales order line cannot be saved with a discount above 15 percent unless a reason is filled. In the user exit library for the line table, ue.after.before.save.object(mode) checks the two fields. If the rule fails it calls dal.set.error.message with a customer message code and returns DALHOOKERROR. Because the rule sits in the DAL layer rather than the session script, it also fires for imports, BOD processing and any script that uses dal.change.object, dal.set.field and dal.save.object. A script that writes with db.update directly would skip it, which is why integrations should use the DAL functions.
Version differences and gotchas
Not every table has a DAL 2 script; tables outside business objects still use DAL 1, and their sessions may keep business logic in UI scripts. User exits are preferred over editing the standard DAL in a customer VRC, because standard solutions overwrite the DAL but not your UE library. Keep hooks fast: property hooks such as is.valid and is.readonly can run many times while a form is open. Never commit or abort inside a hook. Use message codes for errors so they translate.
- Before hooks validate and reject, after hooks follow up
- Use DAL functions in scripts, not direct db calls, when rules must run
- Test insert and update modes separately
- Retest UE libraries after each solution or feature pack
Frequently Asked Questions
What is the DAL in Infor LN?
The Data Access Layer is a library linked to a table that holds its integrity rules and business logic. Every insert, update or delete that goes through the DAL runs its object and property hooks, whether the call comes from a session, an import, a BOD or a script using the DAL functions.
What is the difference between DAL 1 and DAL 2?
DAL 1 scripts usually contain database logic only, with some business logic left in UI scripts. DAL 2 scripts contain all business logic for a table and exist only for tables used in predefined business objects. DAL 2 also adds business method hooks that enable or hide form commands.
How do I add logic without changing the standard DAL?
Create a user exit library for the table (check the naming rule in the Programmer's Guide for your release) and implement the user exit hooks such as ue.after.before.save.object. The standard DAL calls them, and your code stays separate from standard solutions.
Where is the Infor standard DAL documentation?
The Data Access Layer chapter in the Infor ES Programmer's Guide describes the hooks and functions, and the LN Tools online help (DAL 1 Overview and DAL 2 Overview) explains where scripts are maintained. Both are on docs.infor.com for each Enterprise Server release.
If you want developers to ask your LN DAL and UE code base questions in plain English on your own servers, we can index it privately.
Related Tools
Infor LN DAL Hook Review Checklist
Review checklist for LN data access layer (DAL) scripts: hook choice, validation, error handling, performance and upgrade safety.
Infor LN & BaanInfor LN Tools Administration Sessions Reference (ttaad, ttadv, ttpmc)
The ttaad, ttadv, ttpmc and related Tools sessions an LN 10.x administrator or developer uses every week, with what to do there and what to run next.
Infor LN & BaanInfor LN 4GL Session Script Template
Generate a clean Baan / Infor LN 4GL session script skeleton with declaration, field, choice and table I/O sections.
Infor LN & BaanInfor LN BOD Publishing Sessions and Nouns Reference
Searchable map of the BOD nouns Infor LN 10.x publishes to ION, the initial load session for each (tcbod0200m000, tdbod0200m000, whbod0200m000 and more) and the setup sessions around them.
More Developer Tools tools
See all- Infor LN DAL Script Template Generator
- Infor LN User Exit (UE) DLL Template Generator
- Infor LN Report Script Template Generator
- Infor LN ION API OAuth 2.0 REST Call Generator (Python)
- Infor LN Inbound Process.SalesOrder BOD XML Template
- SAP Sales Order ABAP SELECT Generator (VBAK, VBAP, VBFA)
- SAP Sales Order Create BAPI ABAP Generator (BAPI_SALESORDER_CREATEFROMDAT2)
- SAP ABAP Open Items SELECT Generator
- SAP ACDOCA SQL Query Generator
Keep exploring
Free tools
- Infor LN DAL Script Template GeneratorGenerate a Data Access Layer (DAL) script skeleton for an LN table with object hooks, a field check hook, a mandatory hook and error message handling.
- Infor LN DAL Hook Review ChecklistReview checklist for LN data access layer (DAL) scripts: hook choice, validation, error handling, performance and upgrade safety.
- Infor LN User Exit (UE) DLL Template GeneratorGenerate a User Exit DLL for an LN table that adds your own logic around the standard save and delete handling, without changing standard code.
ERP fixes and how-tos
- Logic Deactivation Session in Infor LNWhat logic deactivation means in Infor LN, how it relates to DAL business logic, when it is acceptable for data loads or fixes, and the risks to control.
- Infor LN DAL Out of Sync After a Custom Field: Cause and FixInfor LN throws a DAL out of sync error after a custom field is added. Here is why table admin and DAL regeneration must run together, and the fix.
- Infor LN Studio: compile errors when building DAL/4GL codeInfor LN Studio compile errors on DAL and 4GL objects: how to read the build log, common unresolved-reference causes, and when a full rebuild fixes it.