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 :) > Regards. > > 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 > >> > > -- > 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 > -- Best regards, Maxim
