ArchitectureJpaRules

A library of architecture tests to ensure coding conventions are followed for classes annotated with the JPA Entity annotation.

API

ArchitectureJpaRules.java
class ArchitectureJpaRules {
  ArchRule every_jpa_Entity_must_be_annotated_with_DomainObject_nature_of_ENTITY()     (1)
  ArchRule every_jpa_Entity_must_be_annotated_with_XmlJavaAdapter_of_PersistentEntityAdapter()     (2)
  ArchRule every_jpa_Entity_must_be_annotated_as_an_CausewayEntityListener()     (3)
  DescribedPredicate<JavaAnnotation<?>> EntityListeners_with_CausewayEntityListener()
  ArchRule every_jpa_Entity_must_implement_Comparable()     (4)
  ArchRule every_jpa_Entity_must_be_annotated_as_Table_with_uniqueConstraints()     (5)
  ArchRule every_jpa_Entity_must_be_annotated_as_Table_with_schema()     (6)
  ArchRule every_enum_field_of_jpa_Entity_must_be_annotated_with_Enumerable_STRING()     (7)
  ArchRule every_injected_field_of_jpa_Entity_must_be_annotated_with_Transient()     (8)
  ArchRule every_jpa_Entity_must_have_an_id_field()     (9)
  ArchRule every_jpa_Entity_must_have_a_version_field()     (10)
  ClassesShouldConjunction everyJpa_Entity_must_have_a_field_named_and_annotated(String fieldName, Class<? extends Annotation> annotationClass)
  DescribedPredicate<JavaAnnotation<?>> Table_schema()
  DescribedPredicate<JavaClass> areEntities()
  DescribedPredicate<JavaAnnotation<?>> Table_uniqueConstraints()
  ArchRule every_jpa_Entity_must_have_protected_no_arg_constructor()     (11)
  DescribedPredicate<? super JavaClass> areSubtypeEntities()
}
1 every_jpa_Entity_must_be_annotated_with_DomainObject_nature_of_ENTITY()

This rule requires that classes annotated with the JPA Entity annotation must also be annotated with the Apache Causeway DomainObject annotation specifying that its DomainObject#nature() nature is an org.apache.causeway.applib.annotation.Nature#ENTITY entity .

2 every_jpa_Entity_must_be_annotated_with_XmlJavaAdapter_of_PersistentEntityAdapter()

This rule requires that classes annotated with the JPA Entity annotation must also be annotated with the Apache Causeway jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter annotation with a value of org.apache.causeway.applib.jaxb.PersistentEntityAdapter .class .

3 every_jpa_Entity_must_be_annotated_as_an_CausewayEntityListener()

This rule requires that classes annotated with the JPA Entity annotation must also be annotated with the jakarta.persistence.EntityListeners annotation that includes a value of org.apache.causeway.persistence.jpa.applib.integration.CausewayEntityListener.class .

4 every_jpa_Entity_must_implement_Comparable()

This rule requires that classes annotated with the JPA Entity annotation must also be implement Comparable .

5 every_jpa_Entity_must_be_annotated_as_Table_with_uniqueConstraints()

This rule requires that classes annotated with the JPA Entity annotation must also be annotated with the JPA Table annotation which includes Table#uniqueConstraints() uniqueConstraints .

6 every_jpa_Entity_must_be_annotated_as_Table_with_schema()

This rule requires that classes annotated with the JPA Entity annotation must also be annotated with the JPA Table annotation which includes Table#schema() schema}.

7 every_enum_field_of_jpa_Entity_must_be_annotated_with_Enumerable_STRING()

This rule requires that enum fields in classes annotated with the JPA Entity annotation must also be annotated with the JPA Enumerated annotation indicating that they should be persisted as jakarta.persistence.EnumType#STRING string s (rather than ordinal numbers).

8 every_injected_field_of_jpa_Entity_must_be_annotated_with_Transient()

This rule requires that injected fields in classes annotated with the JPA Entity annotation must also be annotated with JPA Transient annotation.

9 every_jpa_Entity_must_have_an_id_field()

This rule requires that classes annotated with the JPA Entity annotation must contain an id field that is itself annotated with Id .

10 every_jpa_Entity_must_have_a_version_field()

This rule requires that classes annotated with the JPA Entity annotation must contain a version field that is itself annotated with jakarta.persistence.Version .

11 every_jpa_Entity_must_have_protected_no_arg_constructor()

This rule requires that concrete classes annotated with the JPA Entity annotation have a no-arg constructor with protected visibility.

Members

every_jpa_Entity_must_be_annotated_with_DomainObject_nature_of_ENTITY()

This rule requires that classes annotated with the JPA Entity annotation must also be annotated with the Apache Causeway DomainObject annotation specifying that its DomainObject#nature() nature is an org.apache.causeway.applib.annotation.Nature#ENTITY entity .

every_jpa_Entity_must_be_annotated_with_XmlJavaAdapter_of_PersistentEntityAdapter()

This rule requires that classes annotated with the JPA Entity annotation must also be annotated with the Apache Causeway jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter annotation with a value of org.apache.causeway.applib.jaxb.PersistentEntityAdapter .class .

Tnis is so that entities can be transparently referenced from XML-style view models.

every_jpa_Entity_must_be_annotated_as_an_CausewayEntityListener()

This rule requires that classes annotated with the JPA Entity annotation must also be annotated with the jakarta.persistence.EntityListeners annotation that includes a value of org.apache.causeway.persistence.jpa.applib.integration.CausewayEntityListener.class .

Tnis is so that entities can be transparently referenced from XML-style view models.

every_jpa_Entity_must_implement_Comparable()

This rule requires that classes annotated with the JPA Entity annotation must also be implement Comparable .

This is so that entities have a natural ordering and can safely be added to parented collections of type java.util.SortedSet .

every_jpa_Entity_must_be_annotated_as_Table_with_uniqueConstraints()

This rule requires that classes annotated with the JPA Entity annotation must also be annotated with the JPA Table annotation which includes Table#uniqueConstraints() uniqueConstraints .

This is so that entities will have an alternative business key in addition to the system-defined surrogate key.

every_jpa_Entity_must_be_annotated_as_Table_with_schema()

This rule requires that classes annotated with the JPA Entity annotation must also be annotated with the JPA Table annotation which includes Table#schema() schema}.

This is so that entity tables are organised into an appropriate structure (ideally mirroring that of the entities).

every_enum_field_of_jpa_Entity_must_be_annotated_with_Enumerable_STRING()

This rule requires that enum fields in classes annotated with the JPA Entity annotation must also be annotated with the JPA Enumerated annotation indicating that they should be persisted as jakarta.persistence.EnumType#STRING string s (rather than ordinal numbers).

The rationale here is that a string is (arguably) more stable than an ordinal number, and is certainly easier to work with when querying the database. The downside is slightly more space to persist the data, and slightly less performant (not that it would be noticeable).

every_injected_field_of_jpa_Entity_must_be_annotated_with_Transient()

This rule requires that injected fields in classes annotated with the JPA Entity annotation must also be annotated with JPA Transient annotation.

The rationale here is that injected services are managed by the runtime and are not/cannot be persisted.

every_jpa_Entity_must_have_an_id_field()

This rule requires that classes annotated with the JPA Entity annotation must contain an id field that is itself annotated with Id .

This is part of the standard contract for JPA entities.

every_jpa_Entity_must_have_a_version_field()

This rule requires that classes annotated with the JPA Entity annotation must contain a version field that is itself annotated with jakarta.persistence.Version .

This is good practice for JPA entities to implement optimistic locking

every_jpa_Entity_must_have_protected_no_arg_constructor()

This rule requires that concrete classes annotated with the JPA Entity annotation have a no-arg constructor with protected visibility.

The rationale is to encourage the use of static factory methods.