@Column (jdo)
The JDO @javax.jdo.annotation.Column
provides metadata describing how JDO/DataNucleus should persist the property to a database RDBMS table column (or equivalent concept for other persistence stores).
Apache Causeway also parses and interprets this annotation in order to build up aspects of its metamodel.
Apache Causeway parses the Moreover, while JDO/DataNucleus will recognize annotations on either the field or the getter method, Apache Causeway (currently) only inspects the getter method. Therefore ensure that the annotation is placed there. |
This section identifies which attributes of @Column
are recognized and used by Apache Causeway.
Nullability
The allowsNull
attribute is used to specify if a property is mandatory or is optional.
For example:
public class Customer {
@javax.jdo.annotations.Column(allowsNull="true")
public String getMiddleInitial() { /* ... */ }
public void setMiddleInitial(String middleInitial) { /* ... */ }
Causeway also provides @Property#optionality attribute. If both are specified, Apache Causeway will check when it initializes for any contradictions, and will fail-fast with an appropriate error message in the log if there are.
You should also be aware that in the lack of either the @Column#allowsNull
or the @Property#optionality
attributes, that the JDO and Apache Causeway defaults differ.
Apache Causeway rule is straight-forward: properties are assumed to be required.
JDO on the other hand specifies that only primitive types are mandatory; everything else is assumed to be optional.
Therefore a lack of either annotation can also trigger the fail-fast validation check.
In the vast majority of cases you should be fine just to add the @Column#allowsNull
attribute to the getter.
But see the documentation for @Property#optionality attribute for discussion on one or two minor edge cases.
Length for String
s
The length
attribute is used to specify the length of java.lang.String
property types as they map to varchar(n)
columns.
For example:
public class Customer {
@javax.jdo.annotations.Column(length=20)
public String getFirstName() { /* ... */ }
public void setFirstName(String firstName) { /* ... */ }
@javax.jdo.annotations.Column(allowsNull="true", length=1)
public String getMiddleInitial() { /* ... */ }
public void setMiddleInitial(String middleInitial) { /* ... */ }
@javax.jdo.annotations.Column(length=30)
public String getLastName() { /* ... */ }
public void setLastName(String lastName) { /* ... */ }
Apache Causeway also provides @Property#maxLength attribute. If both are specified, Apache Causeway will check when it initializes for any contradictions, and will fail-fast with an appropriate error message in the log if there are.
Length/scale for BigDecimal
s
The length()
and scale
attributes are used to infer the precision/scale of java.math.BigDecimal
property types as they map to decimal(n,p)
columns.
For example:
public class Customer {
@javax.jdo.annotations.Column(length=10, scale=2)
public BigDecimal getTotalOrdersToDate() { /* ... */ }
public void setTotalOrdersToDate(BigDecimal totalOrdersToDate) { /* ... */ }
For BigDecimal
s it is also possible to specify the @Digits annotation, whose form is @Digits(integer, fraction)
.
There is a subtle difference here: while @Column#scale()
corresponds to @Digits#fraction()
, the value of @Column#length()
(ie the precision) is actually the sum of the @Digits’ `integer()
and fraction()
parts.
If both are specified, Apache Causeway will check when it initializes for any contradictions, and will fail-fast with an appropriate error message in the log if there are.
Hints and Tips
This seems to be a good place to describe some additional common mappings that use @Column
.
Unlike the sections above, the attributes specified in these hints and tips aren’t actually part of Apache Causeway metamodel.
Mapping foreign keys
The name
attribute can be used to override the name of the column.
References to other objects are generally mapped as foreign key columns.
If there are multiple references to a given type, then you will want to override the name that JDO/DataNucleus would otherwise default.
For example:
public class PartyRelationship {
@Column(name = "fromPartyId", allowsNull = "false")
public Party getFrom() { /* ... */ }
public void setFrom(Party from) { /* ... */ }
@Column(name = "toPartyId", allowsNull = "false")
public Party getTo() { /* ... */ }
public void setTo(Party to) { /* ... */ }
...
}
Mapping Blob
s and Clob
s
Causeway provides custom value types for Blobs and Clobs.
These value types have multiple internal fields, meaning that they corresponding to multiple columns in the database.
Mapping this correctly requires using @Column
within JDO’s @Persistent
annotation.
For example, here’s how to map a Blob
:
private Blob attachment;
@javax.jdo.annotations.Persistent(defaultFetchGroup="false", columns = {
@javax.jdo.annotations.Column(name = "attachment_name"),
@javax.jdo.annotations.Column(name = "attachment_mimetype"),
@javax.jdo.annotations.Column(name = "attachment_bytes", jdbcType = "BLOB", sqlType = "LONGVARBINARY")
})
@Property(
domainEvent = AttachmentDomainEvent.class,
optionality = Optionality.OPTIONAL
)
public Blob getAttachment() { /* ... */ }
public void setAttachment(Blob attachment) { /* ... */ }
And here’s how to map a Clob
(also taken from the todoapp):
private Clob doc;
@javax.jdo.annotations.Persistent(defaultFetchGroup="false", columns = {
@javax.jdo.annotations.Column(name = "doc_name"),
@javax.jdo.annotations.Column(name = "doc_mimetype"),
@javax.jdo.annotations.Column(name = "doc_chars", jdbcType = "CLOB", sqlType = "LONGVARCHAR")
})
@Property(
optionality = Optionality.OPTIONAL
)
public Clob getDoc() { /* ... */ }
public void setDoc(final Clob doc) { /* ... */ }