@Column (jakarta.persistence)
The JPA @jakarta.persistence.Column provides metadata describing how JPA 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 |
This section identifies which attributes of @Column are recognized and used by Apache Causeway.
Nullability
The nullable attribute is used to specify if a property is mandatory or is optional.
For example:
import jakarta.persistence.Column;
public class Customer {
@Column(nullable=true)
@Getter @Setter
private 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#nullable or the @Property#optionality attributes, that the JPA/Eclipselink and Apache Causeway defaults differ.
Apache Causeway rule is straight-forward: properties are assumed to be required.
JPA/Eclipselink on the other hand properties are assumed to be optional.
A lack of either annotation may result in a metamodel validation error.
In the vast majority of cases you should be fine just to add the @Column#nullable attribute to the getter.
But see the documentation for @Property#optionality attribute for discussion on one or two minor edge cases.
Length for Strings
The length attribute is used to specify the length of java.lang.String property types as they map to varchar(n) columns.
For example:
import jakarta.persistence.Column;
public class Customer {
@Column(length=20)
@Getter @Setter
private String firstName;
@Column(length=1, nullable=true)
@Getter @Setter
private String middleInitial;
@Column(length=30)
@Getter @Setter
private 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 BigDecimals
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:
import jakarta.persistence.Column;
import lombok.*;
public class Customer {
@Column(length=10, scale=2)
@Getter @Setter
private BigDecimal totalOrdersToDate;
//...
}
For BigDecimals 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 JPA/Eclipselink would otherwise default.
For example:
import jakarta.persistence.Column;
public class PartyRelationship {
@Column(name = "fromPartyId", nullable = false)
@Getter @Setter
private Party from;
@Column(name = "toPartyId", nullable = false)
@Getter @Setter
private Party to;
// ...
}
Mapping Blobs and Clobs
For example, here’s how to map a Blob:
@AttributeOverrides({
@AttributeOverride(name="name", column=@Column(name="attachment_name")),
@AttributeOverride(name="mimeType",column=@Column(name="attachment_mimeType")),
@AttributeOverride(name="bytes", column=@Column(name="attachment_bytes"))
})
@Embedded
private BlobJpaEmbeddable attachment;
@Property()
@PropertyLayout()
public Blob getPdf() {
return BlobJpaEmbeddable.toBlob(pdf);
}
public void setPdf(final Blob pdf) {
this.pdf = BlobJpaEmbeddable.fromBlob(pdf);
}
And here’s how to map a Clob:
@AttributeOverrides({
@AttributeOverride(name="name", column=@Column(name="doc_name")),
@AttributeOverride(name="mimeType",column=@Column(name="doc_mimeType")),
@AttributeOverride(name="bytes", column=@Column(name="doc_bytes"))
})
@Getter @Setter
private ClobJpaEmbeddable doc;
@Property()
@PropertyLayout()
public Clob getDoc() {
return ClobJpaEmbeddable.toClob(doc);
}
public void setDoc(final Clob doc) {
this.doc = ClobJpaEmbeddable.fromClob(doc);
}
See Also
-
@Column (JPA API javadoc)