This is an automated email from the ASF dual-hosted git repository. danhaywood pushed a commit to branch CAUSEWAY-3866 in repository https://gitbox.apache.org/repos/asf/causeway.git
commit 8557057dd8c4bc0f88becacfcad0ae335b06bf71 Author: Dan Haywood <[email protected]> AuthorDate: Sun Oct 19 10:13:58 2025 +0100 CAUSEWAY-3866: adds docs for Embeddable, Entity, value types --- .../modules/applib-ant/pages/Embeddable.adoc | 81 +++++++++++++++++++++ .../refguide/modules/applib-ant/pages/Entity.adoc | 25 ++++++- .../modules/applib-ant/partials/about/jpa.adoc | 21 ++++-- .../modules/applib-classes/pages/value-types.adoc | 83 ++++++++++++++++++---- 4 files changed, 193 insertions(+), 17 deletions(-) diff --git a/antora/components/refguide/modules/applib-ant/pages/Embeddable.adoc b/antora/components/refguide/modules/applib-ant/pages/Embeddable.adoc new file mode 100644 index 00000000000..6c2f0091d38 --- /dev/null +++ b/antora/components/refguide/modules/applib-ant/pages/Embeddable.adoc @@ -0,0 +1,81 @@ +[#jakarta-persistence-Embeddable] += @Embeddable (jpa) + +:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...] + +The `@jakarta.persistence.Embeddable` is used by JPA to indicate that a class is persisted inline within a containing domain entity. + +== Mutability + +If the embeddable class is mutable, then the semantics are a dependent entity in 1:1 relationship with its containing domain entity. +In Apache Causeway, this should be modelled as a view model, and will be rendered in the UI as a reference (hyperlink) to the associated object. + +If the embeddable class is immutable, then the semantics are closer to a composite value type. +In most cases the framework won't be able to render the object directly, but a representation of the object could be derived. +An example is xref:refguide:persistence:index/jpa/applib/types/BlobJpaEmbeddable.adoc[] and xref:refguide:persistence:index/jpa/applib/types/ClobJpaEmbeddable.adoc[], which persist the state for `Blob` and `Clob` respectively, and which provide convenient helpers to marshal between them. +Other value types could be represented using xref:refguide:valuetypes:index/asciidoc/applib/value/AsciiDoc.adoc[] or similar. + +== Example + +For example: + +[source,java] +.PostalAddress.java +---- +import jakarta.persistence.*; + +@Embeddable // <.> +@AllArgsConstructor +@Getter @Setter +public class PostalAddress { + + private String firstLine; + private String secondLine; + private String city; + private String postalCode; + private String country; + + public AsciiDoc toAsciiDoc() { // <.> + // ... + } + +} +---- +<.> Indicates that this is an embeddable object +<.> Returns a renderable representation of this object + +This could then be used as so: + +[source,java] +.Customer.java +---- +import jakarta.persistence.*; + +@Entity +public class Customer { + + @Embedded // <.> + private PostalAddress homeAddress; + + public AsciiDoc getHomeAddress() { // <.> + return Optional.ofNullable(homeAddress) + .map(CustomerAddress::toAsciiDoc) + .orElse(null); + } + + @Action(semantics = IDEMPOTENT) + public Customer updateHomeAddress( // <.> + String firstLine, + String secondLine, + String city, + String postalCode, + String country) { + this.homeAddress = new PostalAddress(/*...*/); + return this; + } +} +---- +<.> Indicates that the state of the referenced `PostalAddress` should be stored inline within the same table that stores the ``Customer``'s own data +<.> Renders the address using AsciiDoc +<.> Allows the state of the embedded object to be updated (or replaced). + diff --git a/antora/components/refguide/modules/applib-ant/pages/Entity.adoc b/antora/components/refguide/modules/applib-ant/pages/Entity.adoc index 082e79e690b..36ddf736735 100644 --- a/antora/components/refguide/modules/applib-ant/pages/Entity.adoc +++ b/antora/components/refguide/modules/applib-ant/pages/Entity.adoc @@ -7,7 +7,30 @@ The `@jakarta.persistence.Entity` is used by JPA to indicate that a class is a domain entity to be persisted to the database. -Apache Causeway also checks for this annotation ... +For example: + +[source,java] +.Customer.java +---- +import jakarta.persistence.*; + +@Entity // <.> +public class Customer { + + @Id // <.> + @GeneratedValue(strategy = GenerationType.AUTO) // <2> + @Column(name = "id", nullable = false) // <2> + private Long id; + + // ... + +} +---- +<.> Indicates that this entity is a JPA entity +<.> JPA entities are required to declare an identifier. +It's very common for this to be a surrogate identifier, with the value assigned by the database when the object is persisted. + +Apache Causeway currently does not infer any other semantics from this annotation. [NOTE] ==== diff --git a/antora/components/refguide/modules/applib-ant/partials/about/jpa.adoc b/antora/components/refguide/modules/applib-ant/partials/about/jpa.adoc index fcc9f96d1a0..bec4ef2ff53 100644 --- a/antora/components/refguide/modules/applib-ant/partials/about/jpa.adoc +++ b/antora/components/refguide/modules/applib-ant/partials/about/jpa.adoc @@ -15,10 +15,21 @@ The table below lists the xref:pjpa:ROOT:about.adoc[JPA/EclipseLink] annotations |Layer |Applies to +|xref:refguide:applib-ant:Embeddable.adoc[@jakarta. + +persistence. + +Embeddable] +|Indicates that the class is an embeddable (and ideally immutable) value object. +Embeddable objects are stored in-line with a containing entity (which uses the `@Embedded` annotation to do so). -|xref:refguide:applib-ant:Entity.adoc[@jakarta.persistence. + + +|Domain / persistence +|Class + + +|xref:refguide:applib-ant:Entity.adoc[@jakarta. + +persistence. + Entity] -|Flags that the class is an entity, creating an abstraction layer through which the Causeway framework interacts with the underlying persistent domain object. +|Indicates that the class is a entity, mapping to a (usually updateable) table or view in the underlying RDBMS. |Domain / persistence |Class @@ -40,13 +51,15 @@ Causeway also parses the following JPA annotations, but the metadata is currentl |Applies to -|`@jakarta.persistence. + +|`@jakarta. + +persistence. + Transient` |Unused |Persistence |Property -|`@jakarta.persistence. + +|`@jakarta. + +persistence. + Table` |Unused |Persistence diff --git a/antora/components/refguide/modules/applib-classes/pages/value-types.adoc b/antora/components/refguide/modules/applib-classes/pages/value-types.adoc index ad739345515..ca6c1293db6 100644 --- a/antora/components/refguide/modules/applib-classes/pages/value-types.adoc +++ b/antora/components/refguide/modules/applib-classes/pages/value-types.adoc @@ -7,9 +7,9 @@ == Built-in -Apache Causeway can render and persist all of the JDK primitives and wrapper classes, and a number of other JDK (7.x) classes that represent value types. +Apache Causeway can render and persist all of the JDK primitives and wrapper classes, and a number of other JDK classes that represent value types. -It also supports some of the link:http://www.joda.org/joda-time/[Joda-Time] datatypes, and a number of value types that are shipped by the framework itself. +It also supports a number of value types that are shipped by the framework itself. In addition to primitives, the JDK Classes supported are: @@ -17,7 +17,10 @@ In addition to primitives, the JDK Classes supported are: ** `java.lang.Boolean`, `java.lang.Character`, `java.lang.Double`, `java.lang.Float`, `java.lang.Long`, `java.lang.Integer`, `java.lang.Short`, `java.lang.Byte` -* `java.lang.String` +* strings and similar: classes: + +** `java.lang.String` +** any enum (subtype of `java.lang.Enum`) * numeric data types: @@ -31,29 +34,85 @@ In addition to primitives, the JDK Classes supported are: ** `java.sql.Timestamp` ** `java.util.Date` +* JDK 8 datetime types: -== Joda Time - -It also supports these Joda-Time classes: +** `java.time.LocalDate` +** `java.time.LocalTime` +** `java.time.LocalDateTime` +** `java.time.OffsetDateTime` +** `java.time.OffsetTime` +** `java.time.ZonedDateTime` -* `org.joda.time.DateTime` -* `org.joda.time.LocalDateTime` -* `org.joda.time.LocalDate` +* miscellaneous: +** `java.net.URL` +** `java.util.UUID` +** `java.util.Locale` +** `java.awt.BufferedImage` +* xref:latest@vw:fullcalendar:about.adoc[] defines its own `CalendarEvent` value type. == Framework-defined The framework also defines a number of custom value types: + + + * xref:refguide:applib:index/value/Blob.adoc[Blob] * xref:refguide:applib:index/value/Clob.adoc[Clob] * xref:refguide:applib:index/value/Markup.adoc[Markup] -* xref:refguide:applib:index/value/LocalResourcePath.adoc[LocalResourcePath] ++ +Rendered as HTML. + * xref:refguide:applib:index/value/Password.adoc[Password] ++ +Holds a string whose value is suppressed in the UI. ++ +CAUTION: Note that this string is unencrypted. + +* xref:refguide:applib:index/value/LocalResourcePath.adoc[LocalResourcePath] ++ +Represents a local resource relative to the application's context root (eg a servlet or controller). ++ +Actions that return results of this type result in a browser redirect to the resource. +This is therefore a way to redirect to a custom controller. + +* xref:refguide:applib:index/graph/tree/TreePath.adoc[TreePath] and xref:refguide:applib:index/graph/tree/TreeNode.adoc[TreeNode] ++ +These can be used to render filesystem structures and similar + +In addition, there are a number of non-core value types that can be brought in individually: + +** xref:refguide:valuetypes:index/asciidoc/applib/value/AsciiDoc.adoc[] ++ +Rendered as HTML. + +** xref:refguide:valuetypes:index/markdown/applib/value/Markdown.adoc[] ++ +Rendered as HTML. + +** xref:refguide:valuetypes:index/vega/applib/value/Vega.adoc[] ++ +Rendered as a dynamic graph. +Content is a graph as described using the link:https://vega.github.io/vega-lite/[Vega-lite] grammar. + +More details of the above non-core value types can be found in the xref:valuetypes:ROOT:about.adoc[Value Types] catalog. + +The core framework also defines a number of value types whose use is primarily internal: + +* xref:refguide:applib:index/services/bookmark/Bookmark.adoc[Bookmark] +* anything supported by xref:refguide:applib:index/services/bookmark/IdStringifier.adoc[IdStringifier] ++ +Used by the xref:userguide:commandlog:about.adoc[], xref:userguide:executionlog:about.adoc[], xref:userguide:executionoutbox:about.adoc[] and xref:security:sessionlog:about.adoc[] externsions modules so that their application primary keys of their corresponding entities are recognised as value types + +* `ApplicationFeatureIdValueSemantics` + +The xref:refguide:schema:about.adoc[] of XSDs define a number of DTOs (persisted by the above core extensions) which are also recognised as value types: -In addition, there are a number of non-core value types that can be brought in individually. -These can be found in the catalog of xref:valuetypes:ROOT:about.adoc[Value Types]. +* xref:refguide:schema:cmd.adoc[CommandDto] (and an XML pretty-render variant) +* xref:refguide:schema:ixn.adoc[InteractionDto] (and an XML pretty-render variant) +* xref:refguide:schema:chg.adoc[ChangesDto] (and an XML pretty-render variant)
