Richard Zowalla created OPENJPA-3017:
----------------------------------------

             Summary: @Convert on a collection attribute is ignored and the 
attribute is silently not persisted
                 Key: OPENJPA-3017
                 URL: https://issues.apache.org/jira/browse/OPENJPA-3017
             Project: OpenJPA
          Issue Type: Bug
    Affects Versions: 4.1.1
            Reporter: Richard Zowalla
            Assignee: Richard Zowalla


An {{@Convert}} annotation on a collection\-valued attribute is not honoured, 
and the attribute is silently excluded from the mapping. Neither an exception 
nor an error is raised, and the data is lost without notice.

Reduced case: an entity declaring

{code:java}
@Convert\(converter = ItemListConverter.class\)
private List items = new ArrayList<>\(\);
{code}

where {{ItemListConverter}} implements {{AttributeConverter, String>}} and 
{{Item}} is a plain bean. Observed behaviour on 4.2.0\-SNAPSHOT with Derby:* 
{{ClassMapping.getField\("items"\)}} returns {{null}}, so the field is not a 
managed field at all;
* no column is generated for it;
* a {{persist\(\)}} followed by a {{find\(\)}} in a fresh context returns an 
empty list, with no exception at any point;
* the sole trace is one warning stating that the field is "not a default 
persistent type, and do not have any annotations indicating their persistence 
strategy", from which it follows that {{@Convert}} is not counted as an 
indication of a persistence strategy. In a run of the full test suite several 
hundred such warnings are emitted, so the one that matters is easily missed.

Two defects follow. First, {{@Convert}} should be recognised as declaring a 
persistence strategy. Second, where the conversion cannot be applied, the 
attribute must not be dropped in silence; an error naming the attribute and the 
reason is required.

On the specified semantics: {{@Convert}} applied to a collection attribute 
other than a {{Map}}, with no {{attributeName}}, converts the _elements_ of the 
collection, which would require {{AttributeConverter}} together with 
{{@ElementCollection}}. A converter whose attribute type is the collection 
itself, mapping the whole collection to a single column, is a provider 
extension; Hibernate admits it. Whichever reading is implemented, the present 
behaviour is wrong, because an unsupported mapping is accepted and then ignored.

Reported on the development list by Francesco Chicchiriccò while testing Apache 
Syncope master against 4.2.0\-SNAPSHOT. In that configuration the attribute is 
managed and the failure is instead

{noformat}
org.apache.openjpa.util.MetaDataException: You have supplied columns for
"...JPARealm.plainAttrs", but this mapping cannot
have columns in this context.
    at 
org.apache.openjpa.jdbc.meta.MappingInfo.assertNoSchemaComponents\(MappingInfo.java:384\)
    at 
org.apache.openjpa.jdbc.meta.strats.HandlerFieldStrategy.map\(HandlerFieldStrategy.java:84\)
{noformat}

which arises because the handler derived from the converter is installed and 
the element mapping is then found to carry columns. That path did not reproduce 
from the annotations alone, neither with a {{Serializable}} element type nor 
with a non\-final field, and the configuration difference is still to be 
established. The message is in any case opaque with respect to the cause.

A workaround exists and was verified: the converted form serves as the 
persistent attribute, that is a {{String}} column holding the serialised value, 
the collection is marked {{@Transient}}, and the two directions are carried out 
in {{@PrePersist}}/{{@PreUpdate}} and {{@PostLoad}}. The OpenJPA extensions 
{{@Externalizer}} and {{@Factory}} offer no alternative, as {{@Persistent}} 
rejects a field of {{List}} type.





--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to