[
https://issues.apache.org/jira/browse/OPENJPA-3073?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18143584#comment-18143584
]
ASF subversion and git services commented on OPENJPA-3073:
----------------------------------------------------------
Commit b566952e075994da66ece3bc787a5cdc36d97488 in openjpa's branch
refs/heads/OPENJPA-3075 from Richard Zowalla
[ https://gitbox.apache.org/repos/asf?p=openjpa.git;h=b566952e0 ]
[OPENJPA-3073] Attribute of a non-Serializable type converted only by an
autoApply converter is silently left out of the mapping (#299)
* [OPENJPA-3073] Map an attribute that only an auto-apply converter makes basic
An attribute without a mapping annotation was persistent by default only
if its type was a basic type, an embeddable or serializable. An attribute
of a value class or record that does not implement Serializable got no
persistence strategy, so PersistenceMetaDataDefaults left it out of the
mapping with only a warning - even when a @Converter(autoApply = true) was
registered for its type - and its value was never stored. Declaring it
@Basic failed with "isn't supported by declared persistence strategy".
Jakarta Persistence 3.2 section 3.9 considers a converted attribute a
basic attribute and applies an auto-apply converter to all attributes of
its target type. getPersistenceStrategy() and isDefaultPersistent() now
consult the auto-apply registry of the MetaDataRepository, which
PersistenceMetaDataFactory.load() fills before any class is parsed, and
parseBasic() accepts such an attribute instead of asking for
serialization. Identifier, version, enumerated and temporal attributes
and attributes with a @Convert of their own, including
@Convert(disableConversion = true), are left alone, as is an attribute of
such a type without any converter.
The attribute gets a new column of the converter's database type on
upgrade, so openjpa.Compatibility=MapAutoApplyConvertedFields=false
restores the 4.1.x mapping of unannotated attributes. @Basic attributes
are converted either way, since 4.1.x rejected them.
The test entities are enhanced at runtime: the build-time enhancer of the
test module sees no persistence unit and therefore no auto-apply
converter, and an enhanced class keeps the fields it was enhanced with.
For the same reason TestEnhancementWithMultiplePUs skips the @Basic test
entity.
* [OPENJPA-3073] Document the mapping of auto-apply converted attributes that
are not serializable
Describe the new column, the exceptions, the need to list the converter
for runtime and build-time enhancement, and the MapAutoApplyConvertedFields
option in the migration considerations, and add an Upgrade Notes section to
the release notes.
* [OPENJPA-3073] Map an attribute of a non-serializable interface type through
its auto-apply converter
JavaTypes gives an interface that does not extend Serializable the type
code PC_UNTYPED, not OBJECT, so an attribute declared with such an
interface stayed out of the mapping without an annotation and failed with
@Basic, even with an auto-apply converter of exactly that interface.
isAutoApplyConverted() now accepts PC_UNTYPED as well, and parseBasic()
gives a converted attribute of that type code the type code OBJECT, so
that the kernel no longer treats the converted value as a relation to an
entity and tries to cascade to it.
* [OPENJPA-3073] Document where MapAutoApplyConvertedFields has to be set
The enhancer decides which fields are persistent, so the option has to be
seen by the enhancer as well and classes have to be enhanced again after
it changes. Also mention interface types, and limit the disableConversion
statement to a @Convert on the attribute itself: a class-level
@Convert(attributeName=..., disableConversion=true) on an entity does not
keep an attribute inherited from a mapped superclass out of the mapping.
* [OPENJPA-3073] Add the issue to the release notes
---------
Co-authored-by: Maxim Solodovnik <[email protected]>
> Attribute of a non-Serializable type converted only by an autoApply converter
> is silently left out of the mapping
> -----------------------------------------------------------------------------------------------------------------
>
> Key: OPENJPA-3073
> URL: https://issues.apache.org/jira/browse/OPENJPA-3073
> Project: OpenJPA
> Issue Type: Bug
> Reporter: Richard Zowalla
> Assignee: Richard Zowalla
> Priority: Major
> Fix For: 4.2.0
>
>
> Description:
> An entity or embeddable attribute whose type does not implement
> java.io.Serializable (for example a final value class or a record) and that
> has no mapping annotation is not persisted, even though a
> @Converter(autoApply = true) AttributeConverter<X, Y> is registered for its
> type. OpenJPA only logs 'Fields "..." are not a default persistent type, and
> do not have any annotations indicating their persistence strategy. They will
> be treated as non-persistent.' The attribute gets no column, its value is
> lost on persist, JPQL that references it fails with 'No field named "..."',
> and the metamodel has no such attribute. If the attribute is declared @Basic
> instead, the persistence unit fails with 'The type of field "..." isn't
> supported by declared persistence strategy "Basic"'.
>
> Example:
> public record Weight(long grams) \{ }
> @Converter(autoApply = true)
> public class WeightConverter implements AttributeConverter<Weight, Long> \{
> ... }
> @Entity public class Parcel \{ @Id long id; Weight weight; } // weight is
> never stored
>
> Jakarta Persistence 3.2, section 3.9: "A converted attribute is considered a
> basic attribute, since, with the aid of the converter, its values can be
> represented as instances of a basic type" and "If the value of the autoApply
> element of the Converter annotation is true, the converter is automatically
> applied to all attributes of the target type".
>
> Cause:
> PersistenceMetaDataDefaults.getPersistenceStrategy()/isDefaultPersistent()
> decide whether an unannotated attribute is persistent without looking at the
> auto-apply converter registry of the MetaDataRepository. They only accept
> basic types, enums, embeddables, Serializable types and an explicit @Convert.
> The registry is only used later, in FieldMetaData.resolve(), and only for
> fields that are already persistent.
> AnnotationPersistenceMetaDataParser.parseBasic() likewise rejects @Basic on
> such a type.
>
> Fix: such an attribute becomes a basic attribute mapped through its
> auto-apply converter, with a column of the converter's database type. This
> applies to field and property access and inside embeddables. Identifier,
> version, @Enumerated and @Temporal attributes and attributes with their own
> @Convert (including disableConversion = true) are excluded, as the
> specification requires. An attribute of such a type without any converter is
> still left out with a warning.
>
> Upgrade
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)