Hum, this is not what I am seeing at

https://github.com/apache/openjpa/pull/220/changes#diff-b2a7225b359717a255a5118c3996fa15b43ba365c6b1812e3b20ccf064268b02R32

e.g.

@Converter
public class ItemListConverter implements AttributeConverter<List<Item>, 
String> {

while we have

@Converter
public class PlainAttrListConverter implements AttributeConverter<List<PlainAttr>, 
String> {

On 22/10/26 15:11, Maxim Solodovnik wrote:
I believe you still need to change your converter to have 2 generic
parameters AttributeConverter<PlainAttr, ?>

On Thu, 22 Oct 2026 at 20:06, Francesco Chicchiriccò
<[email protected]> wrote:
So I went ahead, built the branch OPENJPA-3017 locally, then tried again with 
Syncope but... got the same identical stacktrace.

Is there any non-default setting I should apply?

Thank you.
Regards.

On 22/10/26 11:28, Francesco Chicchiriccò wrote:
On 22/10/26 11:24, Maxim Solodovnik wrote:
On Thu, 22 Oct 2026 at 16:22, Francesco Chicchiriccò
<[email protected]> wrote:
Hi Richard,
I saw (and approved) your PR, thank you!

Related to:
As an interim mapping, the converted form may serve as the persistent 
attribute: a String column holding the JSON, the List marked @Transient, and 
the two directions be done in @PrePersist/@PreUpdate and @PostLoad maybe?
this is the approach we follow up to Syncope 4.1.x, which is based on OpenJPA 
4.1.1.

Some background information.
A while ago we switched to Hibernate ORM because of their support for JPA 3.2 
(and the license change too, of course) since it was required by the Spring 
Boot platform upgrade.
OpenJPA was not ready at that time but now, considering the recent efforts 
here, we are reconsidering; only, we would rather not loose the code 
improvements applied so far.

Let's see how things are going after merging your PR, fingers crossed.
You can test from branch :)
That's also true ;-)
I cannot dedicate much time today but this is definitely something possible, 
maybe I'll leave it on background and report afterwards.

On 21/10/26 21:48, Richard Zowalla wrote:
Hi Francesco,

Nothing obvious is missing. I see 2 things:

The first concerns the mapping itself. @Convert applied to a collection attribute converts 
the elements, so List<PlainAttr> would require AttributeConverter<PlainAttr, ?> 
together with @ElementCollection. PlainAttrListConverter converts the collection as a whole 
into a single column, which Hibernate accepts but which is undefined behaviour (according 
to the spec), and the mapping is therefore not portable.

The second concerns a defect on our side, for which we need to fill a bug. 
Reduced to an entity holding a List field and a whole-collection converter, 
OpenJPA does not register the field at all: no column is generated, and a 
persist followed by a find yields an empty list without an error. The sole 
trace is a warning that the field has no annotation indicating a persistence 
strategy, from which it follows that @Convert is not treated as one. Silent 
loss of the attribute is a more concerning outcome, more so than the exception 
you observed.

The exception itself did not reproduce from those annotations alone, neither 
with a Serializable element type nor with a non-final field. Its origin is 
HandlerFieldStrategy.map, which installs the handler derived from the converter 
and then rejects columns supplied for the element; the field is thus managed in 
your configuration and unmanaged in my test setup. To check the difference  we 
would need to know whether plainAttrs is declared in an orm.xml, whether any 
@Access, @Basic or @Column reaches it by way of Attributable, Realm or an 
attribute override, and which openjpa.* properties the unit sets. As an interim 
mapping, the converted form may serve as the persistent attribute: a String 
column holding the JSON, the List marked @Transient, and the two directions be 
done in @PrePersist/@PreUpdate and @PostLoad maybe?

Gruß
Richard

Am 21.10.2026 um 12:45 schrieb Francesco Chicchiriccò <[email protected]>:

Hi all,
I am testing OpenJPA 4.2.0-SNAPSHOT against Syncope master branch, which is 
currently using Hibernate ORM 7.4.

The first error I am encountering is related to [1] e.g.

@Convert(converter = PlainAttrListConverter.class)
private final List<PlainAttr> plainAttrs = new ArrayList<>();

where PlainAttr [2] is a Java bean configured for JSON serialization and 
PlainAttrListConverter[3] is an AttributeConverter leveraging Jackson for this 
purpose.

This works fine under Hibernate, but throws the following exception with 
OpenJPA 4.2.0-SNAPSHOT:

<openjpa-4.2.0-SNAPSHOT-ra2c8177 fatal user error> org.apache.openjpa.util.MetaDataException: 
You have supplied columns for 
"org.apache.syncope.core.persistence.jpa.entity.JPARealm.plainAttrs<element:class 
org.apache.syncope.core.persistence.api.entity.PlainAttr>", 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)
           at 
org.apache.openjpa.jdbc.meta.FieldMapping.setStrategy(FieldMapping.java:148)
           at 
org.apache.openjpa.jdbc.meta.RuntimeStrategyInstaller.installStrategy(RuntimeStrategyInstaller.java:87)
           at 
org.apache.openjpa.jdbc.meta.FieldMapping.resolveMapping(FieldMapping.java:519)
           at 
org.apache.openjpa.jdbc.meta.FieldMapping.resolve(FieldMapping.java:470)
           at 
org.apache.openjpa.jdbc.meta.ClassMapping.resolveNonRelationMappings(ClassMapping.java:1066)
           at 
org.apache.openjpa.jdbc.meta.MappingRepository.prepareMapping(MappingRepository.java:420)
           at 
org.apache.openjpa.meta.MetaDataRepository.preMapping(MetaDataRepository.java:780)
           at 
org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.java:667)
           at 
org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:427)
           at 
org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:398)
           at 
org.apache.openjpa.persistence.PersistenceMetaDataDefaults.getCachedSuperclassMetaData(PersistenceMetaDataDefaults.java:355)
           at 
org.apache.openjpa.persistence.PersistenceMetaDataDefaults.determineAccessType(PersistenceMetaDataDefaults.java:381)
           at 
org.apache.openjpa.persistence.PersistenceMetaDataDefaults.populate(PersistenceMetaDataDefaults.java:317)
           at 
org.apache.openjpa.meta.MetaDataRepository.addMetaData(MetaDataRepository.java:933)
           at 
org.apache.openjpa.meta.MetaDataRepository.addMetaData(MetaDataRepository.java:918)
           at 
org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser.getMetaData(AnnotationPersistenceMetaDataParser.java:828)
           at 
org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser.parseClassAnnotations(AnnotationPersistenceMetaDataParser.java:582)
           at 
org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser.parse(AnnotationPersistenceMetaDataParser.java:440)
           at 
org.apache.openjpa.persistence.PersistenceMetaDataFactory.load(PersistenceMetaDataFactory.java:267)
           at 
org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:595)
           at 
org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:406)
           at 
org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:398)
           at 
org.apache.openjpa.persistence.PersistenceMetaDataDefaults.getCachedSuperclassMetaData(PersistenceMetaDataDefaults.java:355)
           at 
org.apache.openjpa.persistence.PersistenceMetaDataDefaults.determineAccessType(PersistenceMetaDataDefaults.java:381)
           at 
org.apache.openjpa.persistence.PersistenceMetaDataDefaults.populate(PersistenceMetaDataDefaults.java:317)
           at 
org.apache.openjpa.meta.MetaDataRepository.addMetaData(MetaDataRepository.java:933)
           at 
org.apache.openjpa.meta.MetaDataRepository.addMetaData(MetaDataRepository.java:918)
           at 
org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser.getMetaData(AnnotationPersistenceMetaDataParser.java:828)
           at 
org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser.parseClassAnnotations(AnnotationPersistenceMetaDataParser.java:582)
           at 
org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser.parse(AnnotationPersistenceMetaDataParser.java:440)
           at 
org.apache.openjpa.persistence.PersistenceMetaDataFactory.load(PersistenceMetaDataFactory.java:267)
           at 
org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:595)
           at 
org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:406)
           at 
org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:398)
           at 
org.apache.openjpa.persistence.meta.MetamodelImpl.<init>(MetamodelImpl.java:91)
           at 
org.apache.openjpa.persistence.EntityManagerFactoryImpl.getMetamodel(EntityManagerFactoryImpl.java:474)
           at 
org.apache.openjpa.persistence.EntityManagerFactoryImpl.getMetamodel(EntityManagerFactoryImpl.java:81)


Is there anything obvious I am missing?

TIA
Regards.

[1] 
https://github.com/apache/syncope/blob/master/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPARealm.java#L83-L84
[2] 
https://github.com/apache/syncope/blob/master/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/PlainAttr.java
[3] 
https://github.com/apache/syncope/blob/master/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/converters/PlainAttrListConverter.java--

--
Francesco Chicchiriccò

Tirasa - Open Source Excellence
http://www.tirasa.net/

Member at The Apache Software Foundation
Syncope, Cocoon, Olingo, CXF, OpenJPA
https://about.me/ilgrosso

Reply via email to