Understanding the Application Dictionary

Level: Beginner Module: General Foundation 14 min read Lesson 5 of 47

Overview

  • What you’ll learn: What the Application Dictionary is, how it drives iDempiere’s model-driven architecture, and how metadata tables like AD_Table, AD_Column, AD_Window, AD_Tab, AD_Field, and AD_Reference define the entire application.
  • Prerequisites: Lesson 4 – Navigating the User Interface
  • Estimated reading time: 20 minutes

Introduction

If you have used other ERP systems, you may have noticed that adding a new field or changing a form layout often requires custom code, recompilation, and redeployment. iDempiere takes a fundamentally different approach. At the heart of the system lies the Application Dictionary (commonly abbreviated as AD), a set of metadata tables that describe every window, tab, field, table, column, and reference in the entire application. When the system renders a window, it does not read a hard-coded form definition; instead, it queries the Application Dictionary at runtime and builds the user interface dynamically.

This design philosophy is called model-driven development, and it is one of the most powerful features inherited from the original Compiere project. Understanding the Application Dictionary is the single most important step toward becoming proficient in iDempiere customization and administration.

What Makes the Application Dictionary Revolutionary

Traditional enterprise applications store their form layouts, field definitions, and business rules in compiled source code. To change a label, add a field, or rearrange a form, a developer must modify code, compile, test, and deploy. The Application Dictionary eliminates this bottleneck by storing all of these definitions as data inside the database itself.

Consider what this means in practice:

  • A new column added to a database table can appear on a window within minutes, without writing a single line of Java code.
  • Display logic (showing or hiding fields based on conditions) is configured through metadata expressions, not programmed in source files.
  • Validation rules, default values, and mandatory constraints are all defined as dictionary entries.
  • Changes take effect immediately upon saving the dictionary record and refreshing the window. There is no compilation or deployment step.

The Application Dictionary is not just a convenience feature. It is the architectural foundation upon which the entire iDempiere ecosystem is built. Plugins, localizations, and customizations all interact with the dictionary to extend the system without modifying core code.

The EntityType Concept

Before diving into the individual dictionary tables, it is important to understand the EntityType concept. Every dictionary record carries an EntityType field that identifies who owns that definition. The core system uses the entity type D (for Dictionary). When you create customizations, you should define your own entity type (for example, MYCOMPANY) and assign it to all your custom dictionary records.

This separation serves two critical purposes:

  • Upgrade safety: During a system migration, the upgrade process can distinguish between core records (entity type D) and your custom records, preventing your changes from being overwritten.
  • Packaging: The 2Pack export tool uses entity types to determine which records belong to a plugin or customization package.

Core Dictionary Tables

The Application Dictionary is composed of several interconnected metadata tables. Each table serves a specific role in describing the application structure. Let us walk through them in logical order, from database structure to user interface.

AD_Table: Table Definitions

The AD_Table table registers every database table that iDempiere knows about. Each row in AD_Table describes one database table and includes:

  • TableName: The physical name of the table in the database (e.g., C_Order, M_Product).
  • Name: A human-readable label (e.g., “Order”, “Product”).
  • AccessLevel: Determines who can access the data. Values include System Only (4), Client Only (2), Organization (1), Client+Organization (3), System+Client (6), and All (7).
  • IsView: Indicates whether this entry represents a database view rather than a table.
  • IsDeleteable: Controls whether records can be deleted from the UI.
  • ReplicationType: Used in multi-site replication scenarios.

When you create a new physical table in the database, you must also create a corresponding record in AD_Table. Without this registration, iDempiere has no knowledge of the table’s existence.

AD_Column: Column Definitions

For each table registered in AD_Table, the AD_Column table stores definitions for every column. This is where iDempiere learns about data types, constraints, and relationships. Key attributes include:

Attribute Description
ColumnName Physical column name in the database (e.g., DocumentNo)
Name Display label shown to the user
AD_Reference_ID The data type / display type (String, Integer, Date, Table Direct, etc.)
AD_Reference_Value_ID For lookup columns, points to a specific reference definition
AD_Val_Rule_ID Optional dynamic validation rule that filters lookup values
FieldLength Maximum length for string columns
DefaultValue Default value expression (can include context variables like @#Date@)
IsMandatory Whether the column requires a value
IsIdentifier Whether the column participates in the record’s display string
IsKey Whether this is the primary key column
IsParent Whether this column links to a parent table

The AD_Reference_ID field deserves special attention because it controls both how data is stored and how it is displayed. For instance, a column with reference type Table Direct automatically creates a dropdown that looks up values from the referenced table.

AD_Window: Window Definitions

The AD_Window table defines the top-level windows that users interact with. Each window record includes:

  • Name: The window title displayed in the UI.
  • WindowType: Can be Maintain (for editing data), Transaction (for documents like orders and invoices), or Query Only (read-only).
  • AD_Image_ID: An optional icon for the window.
  • IsSOTrx: For transaction windows, indicates whether this is a sales or purchasing window.

A window by itself does not display any data. It is a container that holds one or more tabs.

AD_Tab: Tab Definitions

Each tab within a window is defined in the AD_Tab table. Tabs are where the real data display begins, because each tab is linked to a specific database table. Critical attributes include:

  • AD_Window_ID: The parent window this tab belongs to.
  • AD_Table_ID: The database table whose data this tab displays.
  • TabLevel: The hierarchy level. Level 0 is the header (main) tab, level 1 is a detail tab, level 2 is a sub-detail, and so on.
  • SeqNo: The display sequence within the window.
  • AD_Column_ID (Parent Link): For child tabs, this specifies which column links back to the parent tab’s record.
  • IsSingleRow: Whether the tab displays one record at a time or in a grid.
  • WhereClause: An optional SQL WHERE clause that filters the records displayed.
  • OrderByClause: Controls the default sort order of records.
  • ReadOnlyLogic: A conditional expression that makes the entire tab read-only.
  • DisplayLogic: A conditional expression that controls tab visibility.

The tab level system is fundamental to iDempiere’s parent-child data navigation. When a user selects a record on a level-0 tab, the level-1 tabs automatically filter to show only related child records.

AD_Field: Field Display Definitions

While AD_Column defines what data exists, AD_Field controls how each column appears on a specific tab. This separation is deliberate: the same column can appear on multiple tabs with different display settings. AD_Field attributes include:

  • AD_Tab_ID: Which tab this field belongs to.
  • AD_Column_ID: Which column this field displays.
  • SeqNo: The display order on the form.
  • IsDisplayed: Whether the field is visible.
  • DisplayLogic: A conditional expression for dynamic visibility (e.g., @IsSOTrx@='Y' to show only for sales transactions).
  • IsSameLine: Whether this field appears on the same row as the previous field.
  • IsReadOnly: Whether the field is editable.
  • AD_FieldGroup_ID: An optional grouping for collapsible field sections.
  • SortNo: Used for default grid sorting.

Display logic expressions use a simple syntax referencing context variables. For example, @DocStatus@='DR' means the field is only visible when the document status is Draft.

AD_Reference: Reference Types

The AD_Reference table defines how lookup fields (dropdowns, search fields) retrieve their values. There are several reference types, each suited to a different scenario:

Reference Type Description Use Case
Table Direct Looks up values from the table whose name matches the column name minus _ID Simple foreign keys like C_BPartner_ID
Table Looks up values from a configured table with custom key, display, and WHERE clause Foreign keys needing filtered or custom display
List Stores predefined name-value pairs directly in the reference Fixed enumerations like document status
Search Like Table but opens a search dialog instead of a dropdown Tables with many records (e.g., Products, BPartners)

When a column’s AD_Reference_ID is set to Table or Search, the AD_Reference_Value_ID points to a specific reference record that defines which table to query, which column is the key, which column provides the display value, and an optional WHERE clause for filtering.

How Changes Propagate Immediately

One of the most striking aspects of the Application Dictionary is its runtime nature. When you modify a dictionary record, the change takes effect the next time the affected window is loaded. The propagation works as follows:

  1. A user or administrator modifies a record in an AD table (for example, changes a field’s DisplayLogic).
  2. The record is saved to the database.
  3. The Application Dictionary cache is cleared (either automatically or via the Cache Reset process).
  4. When any user next opens the affected window, iDempiere reads the updated metadata and renders the window with the new configuration.

There is no need to restart the server, recompile code, or redeploy the application. This immediate feedback loop makes the Application Dictionary an extraordinarily productive tool for both development and administration.

Tip: If your changes do not appear immediately, use the Cache Reset option from the Administration menu. The system caches dictionary data aggressively for performance, and sometimes a manual reset is needed.

Step-by-Step Example: Creating a Simple Window

To solidify your understanding, let us walk through the process of creating a simple window to manage a custom table. Suppose your organization needs to track training courses.

Step 1: Create the Database Table

First, create the physical table in the database:

CREATE TABLE XX_TrainingCourse (
  XX_TrainingCourse_ID NUMERIC(10) NOT NULL,
  AD_Client_ID NUMERIC(10) NOT NULL,
  AD_Org_ID NUMERIC(10) NOT NULL,
  IsActive CHAR(1) DEFAULT 'Y' NOT NULL,
  Created TIMESTAMP NOT NULL,
  CreatedBy NUMERIC(10) NOT NULL,
  Updated TIMESTAMP NOT NULL,
  UpdatedBy NUMERIC(10) NOT NULL,
  Value VARCHAR(40) NOT NULL,
  Name VARCHAR(255) NOT NULL,
  Description VARCHAR(255),
  XX_TrainingCourse_UU VARCHAR(36) DEFAULT NULL,
  CONSTRAINT XX_TrainingCourse_Key PRIMARY KEY (XX_TrainingCourse_ID)
);

Notice the standard columns (AD_Client_ID, AD_Org_ID, IsActive, Created, CreatedBy, Updated, UpdatedBy) that every iDempiere table requires.

Step 2: Register in the Application Dictionary

Open the Table and Column window in iDempiere and create a new record:

  • Set the DB Table Name to XX_TrainingCourse.
  • Set the Name to “Training Course”.
  • Set the EntityType to your custom entity type.
  • Use the Create Columns from DB process to automatically generate AD_Column records for each database column.

Step 3: Create the Window

Open the Window, Tab & Field window:

  • Create a new window record with the name “Training Course” and type “Maintain”.
  • Create a tab at level 0 linked to the XX_TrainingCourse table.
  • Use the Create Fields process to automatically generate AD_Field records for each column.
  • Adjust field sequence, display settings, and labels as needed.

Step 4: Add to the Menu

Open the Menu window and create a new menu entry pointing to your window. Assign it to the appropriate menu tree location.

Step 5: Test

Log out and log back in (or reset the cache), navigate to your new menu entry, and your Training Course window is fully functional with create, read, update, and delete capabilities. No Java code was written.

Key Takeaways

  • The Application Dictionary is a set of metadata tables that define the entire iDempiere application structure, from database tables to user interface elements.
  • Model-driven development means changes to the dictionary take effect immediately without code compilation or redeployment.
  • The core dictionary tables form a hierarchy: AD_Table and AD_Column describe the data model; AD_Window, AD_Tab, and AD_Field describe the UI; AD_Reference defines lookup behavior.
  • EntityType separates core dictionary records from customizations, ensuring upgrade safety.
  • New windows and forms can be created entirely through the dictionary without writing Java code.
  • The AD_Reference system provides flexible lookup mechanisms (Table Direct, Table, List, Search) for foreign key relationships.

What’s Next

Now that you understand the Application Dictionary, the next lesson will focus on Working with Windows and Tabs, where you will learn the header/line pattern, parent-child tab relationships, display logic, and how to navigate complex multi-tab windows like the Business Partner window.

繁體中文

概述

  • 您將學到:什麼是 Application Dictionary、它如何驅動 iDempiere 的模型驅動架構,以及 AD_Table、AD_Column、AD_Window、AD_Tab、AD_Field 和 AD_Reference 等中繼資料表如何定義整個應用程式。
  • 先修條件:第 4 課 — 瀏覽使用者介面
  • 預估閱讀時間:20 分鐘

簡介

如果您使用過其他 ERP 系統,您可能已經注意到,新增一個欄位或更改表單配置通常需要自訂程式碼、重新編譯和重新部署。iDempiere 採取了一種根本不同的方法。系統的核心是 Application Dictionary(通常縮寫為 AD),這是一組中繼資料表,描述了整個應用程式中的每個視窗、頁籤、欄位、資料表、欄和參照。當系統呈現一個視窗時,它不會讀取硬編碼的表單定義;相反,它在執行時查詢 Application Dictionary 並動態構建使用者介面。

這種設計理念稱為模型驅動開發,它是從原始 Compiere 專案繼承的最強大功能之一。了解 Application Dictionary 是精通 iDempiere 自訂和管理的最重要一步。

Application Dictionary 的革命性之處

傳統的企業應用程式將其表單配置、欄位定義和業務規則儲存在編譯的原始碼中。要更改標籤、新增欄位或重新排列表單,開發人員必須修改程式碼、編譯、測試和部署。Application Dictionary 通過將所有這些定義作為資料儲存在資料庫本身中來消除這一瓶頸。

考慮一下這在實際中意味著什麼:

  • 新增到資料庫表的欄可以在幾分鐘內出現在視窗上,無需編寫任何一行 Java 程式碼。
  • 顯示邏輯(根據條件顯示或隱藏欄位)通過中繼資料表達式配置,而不是在原始碼檔案中編程。
  • 驗證規則、預設值和強制性約束都定義為資料字典條目。
  • 變更在儲存資料字典記錄並重新整理視窗後立即生效。沒有編譯或部署步驟。

Application Dictionary 不僅僅是一個便利功能。它是整個 iDempiere 生態系統構建的架構基礎。Plugin、本地化和自訂都與資料字典互動,以在不修改核心程式碼的情況下擴展系統。

EntityType 概念

在深入了解各個資料字典表之前,了解 EntityType 概念很重要。每個資料字典記錄都帶有一個 EntityType 欄位,標識誰擁有該定義。核心系統使用實體類型 D(代表 Dictionary)。當您建立自訂時,應該定義自己的實體類型(例如 MYCOMPANY)並將其分配給所有自訂資料字典記錄。

這種分離有兩個關鍵目的:

  • 升級安全性:在系統遷移期間,升級過程可以區分核心記錄(實體類型 D)和您的自訂記錄,防止您的變更被覆蓋。
  • 打包:2Pack 匯出工具使用實體類型來確定哪些記錄屬於 Plugin 或自訂套件。

核心資料字典表

Application Dictionary 由幾個相互關聯的中繼資料表組成。每個表在描述應用程式結構中扮演特定角色。讓我們按邏輯順序逐一介紹,從資料庫結構到使用者介面。

AD_Table:資料表定義

AD_Table 表註冊 iDempiere 所知道的每個資料庫表。AD_Table 中的每一列描述一個資料庫表,包括:

  • TableName:資料庫中表的實體名稱(例如 C_OrderM_Product)。
  • Name:人類可讀的標籤(例如「Order」、「Product」)。
  • AccessLevel:決定誰可以存取資料。值包括 System Only(4)、Client Only(2)、Organization(1)、Client+Organization(3)、System+Client(6)和 All(7)。
  • IsView:指示此條目是否代表資料庫檢視而不是資料表。
  • IsDeleteable:控制是否可以從 UI 刪除記錄。
  • ReplicationType:用於多站點複製場景。

當您在資料庫中建立新的實體表時,您還必須在 AD_Table 中建立對應的記錄。沒有這個註冊,iDempiere 不知道該表的存在。

AD_Column:欄定義

對於 AD_Table 中註冊的每個表,AD_Column 表儲存每個欄的定義。這是 iDempiere 了解資料類型、約束和關係的地方。主要屬性包括:

屬性 描述
ColumnName 資料庫中的實體欄名稱(例如 DocumentNo
Name 顯示給使用者的標籤
AD_Reference_ID 資料類型/顯示類型(String、Integer、Date、Table Direct 等)
AD_Reference_Value_ID 對於查詢欄,指向特定的參照定義
AD_Val_Rule_ID 可選的動態驗證規則,用於篩選查詢值
FieldLength 字串欄的最大長度
DefaultValue 預設值表達式(可包含上下文變數如 @#Date@
IsMandatory 該欄是否需要值
IsIdentifier 該欄是否參與記錄的顯示字串
IsKey 是否為主鍵欄
IsParent 該欄是否連結到父表

AD_Reference_ID 欄位值得特別關注,因為它控制資料的儲存方式和顯示方式。例如,參照類型為 Table Direct 的欄會自動建立一個下拉選單,從參照的表中查詢值。

AD_Window:視窗定義

AD_Window 表定義使用者互動的頂層視窗。每個視窗記錄包括:

  • Name:在 UI 中顯示的視窗標題。
  • WindowType:可以是 Maintain(用於編輯資料)、Transaction(用於訂單和發票等文件)或 Query Only(唯讀)。
  • AD_Image_ID:視窗的可選圖示。
  • IsSOTrx:對於交易視窗,指示這是銷售還是採購視窗。

視窗本身不顯示任何資料。它是一個容器,包含一個或多個頁籤

AD_Tab:頁籤定義

視窗內的每個頁籤在 AD_Tab 表中定義。頁籤是真正的資料顯示開始的地方,因為每個頁籤都連結到特定的資料庫表。關鍵屬性包括:

  • AD_Window_ID:此頁籤所屬的父視窗。
  • AD_Table_ID:此頁籤顯示其資料的資料庫表。
  • TabLevel:階層層級。層級 0 是標題(主要)頁籤,層級 1 是明細頁籤,層級 2 是子明細,依此類推。
  • SeqNo:視窗內的顯示順序。
  • AD_Column_ID(父連結):對於子頁籤,這指定哪個欄連結回父頁籤的記錄。
  • IsSingleRow:頁籤是一次顯示一筆記錄還是在網格中顯示。
  • WhereClause:可選的 SQL WHERE 子句,用於篩選顯示的記錄。
  • OrderByClause:控制記錄的預設排序順序。
  • ReadOnlyLogic:使整個頁籤為唯讀的條件表達式。
  • DisplayLogic:控制頁籤可見性的條件表達式。

頁籤層級系統是 iDempiere 父子資料導覽的基礎。當使用者在層級 0 頁籤上選擇一筆記錄時,層級 1 頁籤會自動篩選以僅顯示相關的子記錄。

AD_Field:欄位顯示定義

AD_Column 定義存在什麼資料,而 AD_Field 控制每個欄在特定頁籤上的顯示方式。這種分離是刻意的:同一個欄可以在多個頁籤上以不同的顯示設定出現。AD_Field 屬性包括:

  • AD_Tab_ID:此欄位所屬的頁籤。
  • AD_Column_ID:此欄位顯示的欄。
  • SeqNo:表單上的顯示順序。
  • IsDisplayed:欄位是否可見。
  • DisplayLogic:用於動態可見性的條件表達式(例如 @IsSOTrx@='Y' 僅對銷售交易顯示)。
  • IsSameLine:此欄位是否與前一個欄位顯示在同一列。
  • IsReadOnly:欄位是否可編輯。
  • AD_FieldGroup_ID:可摺疊欄位區段的可選分組。
  • SortNo:用於預設網格排序。

顯示邏輯表達式使用簡單的語法來參照上下文變數。例如,@DocStatus@='DR' 表示該欄位僅在文件狀態為草稿時可見。

AD_Reference:參照類型

AD_Reference 表定義查詢欄位(下拉選單、搜尋欄位)如何擷取其值。有幾種參照類型,每種適用於不同的場景:

參照類型 描述 使用案例
Table Direct 從名稱與欄名稱去掉 _ID 後匹配的表中查詢值 簡單的外來鍵如 C_BPartner_ID
Table 從配置的表中使用自訂鍵、顯示和 WHERE 子句查詢值 需要篩選或自訂顯示的外來鍵
List 直接在參照中儲存預定義的名稱-值對 固定的列舉如文件狀態
Search 與 Table 類似但開啟搜尋對話框而不是下拉選單 記錄很多的表(例如 Products、BPartners)

當欄的 AD_Reference_ID 設定為 Table 或 Search 時,AD_Reference_Value_ID 指向一個特定的參照記錄,定義要查詢哪個表、哪個欄是鍵、哪個欄提供顯示值,以及用於篩選的可選 WHERE 子句。

變更如何即時傳播

Application Dictionary 最引人注目的方面之一是其執行時性質。當您修改一個資料字典記錄時,變更在下次載入受影響的視窗時生效。傳播過程如下:

  1. 使用者或管理員修改 AD 表中的記錄(例如,更改欄位的 DisplayLogic)。
  2. 記錄儲存到資料庫。
  3. Application Dictionary 快取被清除(自動或透過 Cache Reset 流程)。
  4. 當任何使用者下次開啟受影響的視窗時,iDempiere 讀取更新的中繼資料並以新配置呈現視窗。

無需重新啟動伺服器、重新編譯程式碼或重新部署應用程式。這種即時回饋循環使 Application Dictionary 成為開發和管理的極其高效的工具。

提示:如果您的變更沒有立即顯示,請使用管理選單中的 Cache Reset 選項。系統為了效能會積極快取資料字典資料,有時需要手動重置。

逐步範例:建立一個簡單的視窗

為了鞏固您的理解,讓我們逐步完成建立一個簡單視窗來管理自訂表的過程。假設您的組織需要追蹤培訓課程。

步驟 1:建立資料庫表

首先,在資料庫中建立實體表:

CREATE TABLE XX_TrainingCourse (
  XX_TrainingCourse_ID NUMERIC(10) NOT NULL,
  AD_Client_ID NUMERIC(10) NOT NULL,
  AD_Org_ID NUMERIC(10) NOT NULL,
  IsActive CHAR(1) DEFAULT 'Y' NOT NULL,
  Created TIMESTAMP NOT NULL,
  CreatedBy NUMERIC(10) NOT NULL,
  Updated TIMESTAMP NOT NULL,
  UpdatedBy NUMERIC(10) NOT NULL,
  Value VARCHAR(40) NOT NULL,
  Name VARCHAR(255) NOT NULL,
  Description VARCHAR(255),
  XX_TrainingCourse_UU VARCHAR(36) DEFAULT NULL,
  CONSTRAINT XX_TrainingCourse_Key PRIMARY KEY (XX_TrainingCourse_ID)
);

請注意每個 iDempiere 表所需的標準欄(AD_Client_ID、AD_Org_ID、IsActive、Created、CreatedBy、Updated、UpdatedBy)。

步驟 2:在 Application Dictionary 中註冊

在 iDempiere 中開啟 Table and Column 視窗並建立新記錄:

  • DB Table Name 設定為 XX_TrainingCourse
  • Name 設定為「Training Course」。
  • EntityType 設定為您的自訂實體類型。
  • 使用 Create Columns from DB 流程自動為每個資料庫欄產生 AD_Column 記錄。

步驟 3:建立視窗

開啟 Window, Tab & Field 視窗:

  • 建立一個名稱為「Training Course」、類型為「Maintain」的新視窗記錄。
  • 建立一個層級 0 的頁籤,連結到 XX_TrainingCourse 表。
  • 使用 Create Fields 流程自動為每個欄產生 AD_Field 記錄。
  • 根據需要調整欄位順序、顯示設定和標籤。

步驟 4:新增到選單

開啟 Menu 視窗並建立一個指向您的視窗的新選單條目。將其分配到適當的選單樹位置。

步驟 5:測試

登出並重新登入(或重置快取),導覽到您的新選單條目,您的 Training Course 視窗就完全可以使用,具備建立、讀取、更新和刪除功能。沒有編寫任何 Java 程式碼。

重點摘要

  • Application Dictionary 是一組定義整個 iDempiere 應用程式結構的中繼資料表,從資料庫表到使用者介面元素。
  • 模型驅動開發意味著對資料字典的變更無需程式碼編譯或重新部署即可立即生效。
  • 核心資料字典表形成一個階層:AD_Table 和 AD_Column 描述資料模型;AD_Window、AD_Tab 和 AD_Field 描述 UI;AD_Reference 定義查詢行為。
  • EntityType 將核心資料字典記錄與自訂分開,確保升級安全性。
  • 新的視窗和表單可以完全透過資料字典建立,無需編寫 Java 程式碼。
  • AD_Reference 系統為外來鍵關係提供靈活的查詢機制(Table Direct、Table、List、Search)。

下一步

現在您已經了解了 Application Dictionary,下一課將重點介紹使用視窗和頁籤,您將學習標題/明細模式、父子頁籤關係、顯示邏輯,以及如何導覽像 Business Partner 視窗這樣的複雜多頁籤視窗。

日本語

概要

  • 学習内容:Application Dictionary とは何か、それが iDempiere のモデル駆動アーキテクチャをどのように推進するか、AD_Table、AD_Column、AD_Window、AD_Tab、AD_Field、AD_Reference などのメタデータテーブルがアプリケーション全体をどのように定義するか。
  • 前提条件:レッスン 4 — ユーザーインターフェースのナビゲーション
  • 推定読了時間:20 分

はじめに

他の ERP システムを使用したことがあれば、新しいフィールドの追加やフォームレイアウトの変更にはカスタムコード、再コンパイル、再デプロイが必要になることが多いことに気付いたかもしれません。iDempiere は根本的に異なるアプローチを取ります。システムの中核には Application Dictionary(一般的に AD と略される)があります。これは、アプリケーション全体のすべてのウィンドウ、タブ、フィールド、テーブル、カラム、参照を記述するメタデータテーブルのセットです。システムがウィンドウをレンダリングする際、ハードコードされたフォーム定義を読み取るのではなく、実行時に Application Dictionary をクエリし、ユーザーインターフェースを動的に構築します。

この設計思想はモデル駆動開発と呼ばれ、元の Compiere プロジェクトから受け継がれた最も強力な機能の 1 つです。Application Dictionary を理解することは、iDempiere のカスタマイズと管理に精通するための最も重要なステップです。

Application Dictionary が革新的である理由

従来のエンタープライズアプリケーションは、フォームレイアウト、フィールド定義、ビジネスルールをコンパイルされたソースコードに格納します。ラベルの変更、フィールドの追加、フォームの再配置を行うには、開発者がコードを修正し、コンパイルし、テストし、デプロイする必要があります。Application Dictionary は、これらの定義をすべてデータベース自体の中にデータとして格納することで、このボトルネックを解消します。

これが実際に何を意味するか考えてみましょう:

  • データベーステーブルに追加された新しいカラムは、Java コードを一行も書かずに、数分以内にウィンドウに表示できます。
  • 表示ロジック(条件に基づくフィールドの表示/非表示)は、ソースファイルにプログラムするのではなく、メタデータの式で設定します。
  • 検証ルール、デフォルト値、必須制約はすべてディクショナリエントリとして定義されます。
  • 変更はディクショナリレコードを保存してウィンドウを更新すると即座に反映されます。コンパイルやデプロイのステップはありません。

Application Dictionary は単なる便利機能ではありません。iDempiere エコシステム全体が構築されるアーキテクチャの基盤です。Plugin、ローカライゼーション、カスタマイズはすべて、コアコードを変更せずにシステムを拡張するためにディクショナリと連携します。

EntityType の概念

個々のディクショナリテーブルに入る前に、EntityType の概念を理解することが重要です。すべてのディクショナリレコードは、その定義の所有者を識別する EntityType フィールドを持っています。コアシステムはエンティティタイプ D(Dictionary の略)を使用します。カスタマイズを作成する際は、独自のエンティティタイプ(例:MYCOMPANY)を定義し、すべてのカスタムディクショナリレコードに割り当てるべきです。

この分離には 2 つの重要な目的があります:

  • アップグレードの安全性:システム移行時に、アップグレードプロセスがコアレコード(エンティティタイプ D)とカスタムレコードを区別でき、変更が上書きされることを防ぎます。
  • パッケージング:2Pack エクスポートツールは、エンティティタイプを使用して、どのレコードが Plugin やカスタマイズパッケージに属するかを判断します。

コアディクショナリテーブル

Application Dictionary は、相互に関連する複数のメタデータテーブルで構成されています。各テーブルは、アプリケーション構造を記述する上で特定の役割を果たします。データベース構造からユーザーインターフェースまで、論理的な順序で見ていきましょう。

AD_Table:テーブル定義

AD_Table テーブルは、iDempiere が認識しているすべてのデータベーステーブルを登録します。AD_Table の各行は 1 つのデータベーステーブルを記述し、以下を含みます:

  • TableName:データベース内のテーブルの物理名(例:C_OrderM_Product)。
  • Name:人間が読めるラベル(例:「Order」、「Product」)。
  • AccessLevel:誰がデータにアクセスできるかを決定します。値には System Only(4)、Client Only(2)、Organization(1)、Client+Organization(3)、System+Client(6)、All(7)があります。
  • IsView:このエントリがテーブルではなくデータベースビューを表すかどうかを示します。
  • IsDeleteable:UI からレコードを削除できるかどうかを制御します。
  • ReplicationType:マルチサイトレプリケーションシナリオで使用されます。

データベースに新しい物理テーブルを作成する場合、AD_Table に対応するレコードも作成する必要があります。この登録がなければ、iDempiere はテーブルの存在を認識しません。

AD_Column:カラム定義

AD_Table に登録されている各テーブルについて、AD_Column テーブルはすべてのカラムの定義を格納します。ここで iDempiere はデータ型、制約、リレーションシップを学習します。主な属性は以下のとおりです:

属性 説明
ColumnName データベース内の物理カラム名(例:DocumentNo
Name ユーザーに表示されるラベル
AD_Reference_ID データ型/表示タイプ(String、Integer、Date、Table Direct など)
AD_Reference_Value_ID ルックアップカラムの場合、特定の参照定義を指す
AD_Val_Rule_ID ルックアップ値をフィルタリングするオプションの動的検証ルール
FieldLength 文字列カラムの最大長
DefaultValue デフォルト値の式(@#Date@ などのコンテキスト変数を含めることができる)
IsMandatory カラムに値が必要かどうか
IsIdentifier カラムがレコードの表示文字列に参加するかどうか
IsKey これが主キーカラムかどうか
IsParent このカラムが親テーブルにリンクするかどうか

AD_Reference_ID フィールドは、データの格納方法と表示方法の両方を制御するため、特に注目に値します。たとえば、参照タイプが Table Direct のカラムは、参照先テーブルから値を検索するドロップダウンを自動的に作成します。

AD_Window:ウィンドウ定義

AD_Window テーブルは、ユーザーが操作するトップレベルのウィンドウを定義します。各ウィンドウレコードには以下が含まれます:

  • Name:UI に表示されるウィンドウタイトル。
  • WindowType:Maintain(データ編集用)、Transaction(注文や請求書などのドキュメント用)、または Query Only(読み取り専用)のいずれか。
  • AD_Image_ID:ウィンドウのオプションアイコン。
  • IsSOTrx:トランザクションウィンドウの場合、これが販売ウィンドウか購買ウィンドウかを示します。

ウィンドウ自体はデータを表示しません。1 つ以上のタブを保持するコンテナです。

AD_Tab:タブ定義

ウィンドウ内の各タブは AD_Tab テーブルで定義されます。各タブは特定のデータベーステーブルにリンクされているため、タブは実際のデータ表示が始まる場所です。重要な属性は以下のとおりです:

  • AD_Window_ID:このタブが属する親ウィンドウ。
  • AD_Table_ID:このタブがデータを表示するデータベーステーブル。
  • TabLevel:階層レベル。レベル 0 はヘッダー(メイン)タブ、レベル 1 は明細タブ、レベル 2 はサブ明細、以下同様。
  • SeqNo:ウィンドウ内の表示順序。
  • AD_Column_ID(親リンク):子タブの場合、どのカラムが親タブのレコードにリンクするかを指定。
  • IsSingleRow:タブが一度に 1 レコードを表示するか、グリッドで表示するか。
  • WhereClause:表示されるレコードをフィルタリングするオプションの SQL WHERE 句。
  • OrderByClause:レコードのデフォルトソート順を制御。
  • ReadOnlyLogic:タブ全体を読み取り専用にする条件式。
  • DisplayLogic:タブの表示/非表示を制御する条件式。

タブレベルシステムは、iDempiere の親子データナビゲーションの基本です。ユーザーがレベル 0 タブでレコードを選択すると、レベル 1 タブは自動的にフィルタリングされ、関連する子レコードのみが表示されます。

AD_Field:フィールド表示定義

AD_Column がどのようなデータが存在するかを定義するのに対し、AD_Field は各カラムが特定のタブにどのように表示されるかを制御します。この分離は意図的です:同じカラムが異なる表示設定で複数のタブに表示できます。AD_Field の属性には以下が含まれます:

  • AD_Tab_ID:このフィールドが属するタブ。
  • AD_Column_ID:このフィールドが表示するカラム。
  • SeqNo:フォーム上の表示順序。
  • IsDisplayed:フィールドが表示されるかどうか。
  • DisplayLogic:動的表示のための条件式(例:@IsSOTrx@='Y' で販売トランザクションの場合のみ表示)。
  • IsSameLine:このフィールドが前のフィールドと同じ行に表示されるかどうか。
  • IsReadOnly:フィールドが編集可能かどうか。
  • AD_FieldGroup_ID:折りたたみ可能なフィールドセクションのオプショナルグループ。
  • SortNo:デフォルトのグリッドソートに使用。

表示ロジック式は、コンテキスト変数を参照するシンプルな構文を使用します。たとえば、@DocStatus@='DR' は、ドキュメントステータスがドラフトの場合にのみフィールドが表示されることを意味します。

AD_Reference:参照タイプ

AD_Reference テーブルは、ルックアップフィールド(ドロップダウン、検索フィールド)がどのように値を取得するかを定義します。いくつかの参照タイプがあり、それぞれ異なるシナリオに適しています:

参照タイプ 説明 使用ケース
Table Direct カラム名から _ID を除いた名前に一致するテーブルから値を検索 C_BPartner_ID のような単純な外部キー
Table カスタムキー、表示、WHERE 句を持つ設定されたテーブルから値を検索 フィルタリングやカスタム表示が必要な外部キー
List 参照内に直接、事前定義された名前と値のペアを格納 ドキュメントステータスのような固定の列挙
Search Table と同様だが、ドロップダウンの代わりに検索ダイアログを開く レコードが多いテーブル(例:Products、BPartners)

カラムの AD_Reference_ID が Table または Search に設定されている場合、AD_Reference_Value_ID は、どのテーブルをクエリするか、どのカラムがキーか、どのカラムが表示値を提供するか、フィルタリング用のオプションの WHERE 句を定義する特定の参照レコードを指します。

変更が即座に反映される仕組み

Application Dictionary の最も注目すべき側面の 1 つは、その実行時の性質です。ディクショナリレコードを変更すると、影響を受けるウィンドウが次に読み込まれたときに変更が反映されます。伝播は以下のように機能します:

  1. ユーザーまたは管理者が AD テーブルのレコードを変更する(たとえば、フィールドの DisplayLogic を変更)。
  2. レコードがデータベースに保存される。
  3. Application Dictionary のキャッシュがクリアされる(自動的に、または Cache Reset プロセスを通じて)。
  4. 任意のユーザーが次に影響を受けるウィンドウを開くと、iDempiere は更新されたメタデータを読み取り、新しい設定でウィンドウをレンダリングする。

サーバーの再起動、コードの再コンパイル、アプリケーションの再デプロイは不要です。この即時フィードバックループにより、Application Dictionary は開発と管理の両方において非常に生産的なツールとなっています。

ヒント:変更がすぐに表示されない場合は、管理メニューの Cache Reset オプションを使用してください。システムはパフォーマンスのためにディクショナリデータを積極的にキャッシュしており、手動リセットが必要な場合があります。

ステップバイステップの例:シンプルなウィンドウの作成

理解を深めるために、カスタムテーブルを管理するシンプルなウィンドウを作成するプロセスを順を追って見ていきましょう。組織がトレーニングコースを追跡する必要があるとします。

ステップ 1:データベーステーブルの作成

まず、データベースに物理テーブルを作成します:

CREATE TABLE XX_TrainingCourse (
  XX_TrainingCourse_ID NUMERIC(10) NOT NULL,
  AD_Client_ID NUMERIC(10) NOT NULL,
  AD_Org_ID NUMERIC(10) NOT NULL,
  IsActive CHAR(1) DEFAULT 'Y' NOT NULL,
  Created TIMESTAMP NOT NULL,
  CreatedBy NUMERIC(10) NOT NULL,
  Updated TIMESTAMP NOT NULL,
  UpdatedBy NUMERIC(10) NOT NULL,
  Value VARCHAR(40) NOT NULL,
  Name VARCHAR(255) NOT NULL,
  Description VARCHAR(255),
  XX_TrainingCourse_UU VARCHAR(36) DEFAULT NULL,
  CONSTRAINT XX_TrainingCourse_Key PRIMARY KEY (XX_TrainingCourse_ID)
);

すべての iDempiere テーブルに必要な標準カラム(AD_Client_ID、AD_Org_ID、IsActive、Created、CreatedBy、Updated、UpdatedBy)に注目してください。

ステップ 2:Application Dictionary への登録

iDempiere で Table and Column ウィンドウを開き、新しいレコードを作成します:

  • DB Table NameXX_TrainingCourse に設定。
  • Name を「Training Course」に設定。
  • EntityType をカスタムエンティティタイプに設定。
  • Create Columns from DB プロセスを使用して、各データベースカラムの AD_Column レコードを自動生成。

ステップ 3:ウィンドウの作成

Window, Tab & Field ウィンドウを開きます:

  • 名前が「Training Course」、タイプが「Maintain」の新しいウィンドウレコードを作成。
  • XX_TrainingCourse テーブルにリンクされたレベル 0 のタブを作成。
  • Create Fields プロセスを使用して、各カラムの AD_Field レコードを自動生成。
  • 必要に応じてフィールドの順序、表示設定、ラベルを調整。

ステップ 4:メニューへの追加

Menu ウィンドウを開き、ウィンドウを指す新しいメニューエントリを作成します。適切なメニューツリーの位置に割り当てます。

ステップ 5:テスト

ログアウトして再ログイン(またはキャッシュをリセット)し、新しいメニューエントリに移動すると、Training Course ウィンドウは作成、読み取り、更新、削除の機能を完全に備えた状態で使用できます。Java コードは一行も書いていません。

重要なポイント

  • Application Dictionary は、データベーステーブルからユーザーインターフェース要素まで、iDempiere アプリケーション構造全体を定義するメタデータテーブルのセットです。
  • モデル駆動開発とは、ディクショナリへの変更がコードのコンパイルや再デプロイなしに即座に反映されることを意味します。
  • コアディクショナリテーブルは階層を形成します:AD_Table と AD_Column はデータモデルを記述し、AD_Window、AD_Tab、AD_Field は UI を記述し、AD_Reference はルックアップの動作を定義します。
  • EntityType はコアディクショナリレコードとカスタマイズを分離し、アップグレードの安全性を確保します。
  • 新しいウィンドウやフォームは、Java コードを書かずにディクショナリのみで完全に作成できます。
  • AD_Reference システムは、外部キーリレーションシップのための柔軟なルックアップメカニズム(Table Direct、Table、List、Search)を提供します。

次のステップ

Application Dictionary を理解したところで、次のレッスンではウィンドウとタブの操作に焦点を当てます。ヘッダー/明細パターン、親子タブのリレーションシップ、表示ロジック、Business Partner ウィンドウのような複雑なマルチタブウィンドウのナビゲーション方法を学びます。

You Missed