Domain Model
The domain object (model) is defined using xml format.
Each files should have proper declaration :
<?xml version="1.0" encoding="UTF-8"?>
<domain-models xmlns="http://axelor.com/xml/ns/domain-models"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://axelor.com/xml/ns/domain-models
http://axelor.com/xml/ns/domain-models/domain-models_4.0.xsd">
<!-- models definitions here -->
</domain-models>
Java reserved keywords can’t be used as field names. SQL reserved keywords (PostgreSQL, MySQL & Oracle) can’t be used as column names. |
Let’s see with an example:
<module name="contact" package="com.axelor.contact.db" />
<entity name="Contact" sequential="true" cachable="true">
<many-to-one name="title" ref="Title"/> (1)
<string name="firstName" required="true" /> (2)
<string name="lastName" required="true" />
<string name="fullName" namecolumn="true" search="firstName,lastName"> (3)
<![CDATA[
if (firstName == null && lastName == null)
return null;
if (title == null)
return firstName + " " + lastName;
return title.getName() + " " + firstName + " " + lastName;
]]></string>
<date name="dateOfBirth"/>
<string name="email" required="true" unique="true" max="100" />
<string name="phone" max="20" massUpdate="true"/>
<string name="notes" title="About me" large="true" />
<one-to-many name="addresses" ref="Address" mappedBy="contact"/> (4)
<finder-method name="findByName" using="fullName" /> (5)
<finder-method name="findByEmail" using="email" />
</entity>
1 | define a many-to-one field title referencing Title object |
2 | define a string field firstName |
3 | define a calculated string field fullName |
4 | define a one-to-many field addresses referencing Address object |
5 | define a custom finder method findByName |
A domain model is defined using <entity>
tag, it supports some attributes.
-
name
- name of the Entity (should begin with upper case letter) -
sequential
- whether to use a new ID sequence (default is true) -
cachable
- whether to make this entity cacheable (default is false) -
repository=[none|default|abstract]
- how to generate repository class -
table
- table name for the entity -
logUpdates
- whether to enable update logging (default is true) -
lang
- language of the generated source code (default is java) -
extends
- inheritance base entity class -
implements
- list of interfaces to implement (generally empty, or confirming the getter/setter) -
persistable
- whether this entity is persistable (in database). -
strategy=[SINGLE|JOINED|CLASS]
- inheritance strategy (default is SINGLE) -
hashAll
- whether to use all the simple non-function fields as hash keys (default is false)
The strategy
attribute can be used on base entity only.
The persistable
attribute can be used to define a non-persitable entity class
annotated with @MappedSuperclass
that can be used as base class of other entities.
The <module>
tag can be used to define package names of the generated entities
& repositories:
<!-- default behavior -->
<module name="contact"
package="com.axelor.contact.db"
repo-package="com.axelor.contact.db.repo"
table-prefix="contact" />
<!-- custom behavior -->
<module name="contact"
package="my.models"
repo-package="my.repos"
table-prefix="my" />
-
name
- is required, used to group entities in a logical module -
package
- is required, used as java package name of the generated entity class -
repo-package
- is optional, used as java package name of the generated repository class, defaults to<package>.repo
-
table-prefix
- is optional, used as table name prefix, defaults to modulename
Fields
The fields of different types are used to define model properties. Fields have some attributes.
Following are the common attribute for all field types:
Attribute | Description |
---|---|
|
name of the field (required) |
|
display title of the field |
|
detailed help string |
|
database column name (if field name is reserved name in underlying database) |
|
whether to generate index of this field |
|
default value of the field |
|
whether the field value is required |
|
whether the field value is readonly |
|
whether the field value is unique (defines unique constraint) |
|
whether the field is hidden by default in user interfaces |
|
whether the field is transient (can’t be saved in db) |
|
whether to use the field as a contractor parameter |
|
whether to consider this field as hashCode candidate |
|
whether to allow mass update on this field |
|
sql formula if this is a formula field |
However, some of these attributes are not applicable to relational fields.
String
The <string>
field is used to define textual data fields.
The field accepts following additional attributes:
Attribute | Description |
---|---|
|
minimum length of the text value |
|
maximum length of the text value |
|
whether to use large text type |
|
comma separated list of field names used by autocompletion UI component to search. |
|
user the specified custom sequence generator |
|
whether the string is multiline text (used by UI components) |
|
whether the field value is translatable |
|
whether the field is storing password text |
example:
<string name="firstName" min="1" />
<string name="lastName"/>
<string name="notes" large="true" multiline="true"/>
The translatable
attribute can be used to mark the field values as translatable.
For example:
<entity name="Product">
<string name="name" translatable="true" />
</entity>
Translated values are stored in same general translation table (no context saved).
Boolean
The <boolean>
field is used to define boolean type fields.
example:
<boolean name="active" />
Integer
The <integer>
field is used to define non-decimal numeric fields.
Attribute | Description |
---|---|
|
minimum value (inclusive) |
|
maximum value (inclusive) |
example:
<integer name="quantity" min="1" max="100"/>
<integer name="count"/>
Long
The <long>
field is used to define non-decimal numeric field where value can’t
be represented by integer
type.
Avoid using this field type as some dbms (oracle) only allows one
long column per table (we already have one for id column)
|
Attribute | Description |
---|---|
|
minimum value (inclusive) |
|
maximum value (inclusive) |
example:
<long name="counter"/>
Decimal
The <decimal>
field is used to define decimal type fields using java.util.BigDecimal
java type.
Attribute | Description |
---|---|
|
minimum value (inclusive) |
|
maximum value (inclusive) |
|
precision of the decimal value (total number of digits) |
|
scale of the decimal value (total number of digits in decimal part) |
example:
<decimal name="price" precision="8" scale="2" />
Date
The <date>
field is used to define fields to store date using org.joda.title.LocalDate
java type.
example:
<date name="orderDate" />
Time
The <time
field is used to define fields to store time values using the
org.joda.time.LocalTime
java type.
example:
<time name="duration" />
DateTime
The <datetime>
field is used to define fields to store datetime values using
the org.joda.time.LocalDateTime
java type.
Attribute | Description |
---|---|
|
whether to use timezone info |
In case of tz
is true, the java type is org.joda.time.DateTime`
example:
<datetime name="startsOn" />
<datetime name="startsOn" tz="true"/>
Binary
The <binary>
field is used to store binary blobs.
Attribute | Description |
---|---|
|
if the field is intended to store image data |
only use this field for small or non-reusable binary data, prefer using
an many-to-one to com.axelor.meta.db.MetaFile .
|
example:
<binary name="photo" image="true" />
<binary name="report" />
ManyToOne
The <many-to-one>
field is used to define a single value reference field using
many-to-one relationship.
Attribute | Description |
---|---|
|
name of the reference entity class (FQN if not in same package) |
example:
<many-to-one name="customer" ref="com.axelor.contact.db.Contact" />
OneToOne
The <one-to-one>
field is used to define a single value reference field using
one-to-one relationship.
Attribute | Description |
---|---|
|
name of the reference entity class (FQN if not in same package) |
|
for bi-directional fields, name of the owner side field |
<!-- defined in Engine object -->
<one-to-one name="car" ref="com.axelor.cars.db.Car" />
<!-- defined in Cat object -->
<one-to-one name="engine" ref="com.axelor.cars.db.Engine" mappedBy="car"/>
OneToMany
The <one-to-many>
field is used to define multi-value fields using one-to-many
relationship.
Attribute | Description |
---|---|
|
name of the reference entity class (FQN if not in same package) |
|
for bi-directional fields, name of the inverse many-to-one field |
|
whether to remove orphaned records (default true) |
|
specify the ordering of the collection value by the given field |
<one-to-many name="items" ref="OrderItem" mappedBy="order" />
<one-to-many name="addresses" ref="Address" mappedBy="contact" />
ManyToMany
The <many-to-many>
field is used to define multi-value fields using many-to-many
relationship.
Attribute | Description |
---|---|
|
name of the reference entity class (FQN if not in same package) |
|
for bi-directional fields, name of the owner side field |
|
specify the ordering of the collection value by the given field |
<many-to-many name="taxes" ref="Tax" />
Index
The <index>
tag can be used to define a composite index.
It is defined by specifying a comma separated list of column names
in the columns
attribute. A name can be defined with the name
attribute.
<index columns="firstName,lastName,fullName" name="idx_names"/>
A index can be defined on a field using index
attribute.
A custom index name can be provided (starting with 'idx_' prefix), else default
index name is generated using table name and column name.
By default, all reference fields, namecolumn, name and code are automatically indexed.
<string name="firstName" required="true" index="true"/>
<string name="lastName" required="true" index="idx_contact_last_name"/>