[oops, did not mean to post the code to users]

I have narrowed it down, and I think these changes will address the issue.

commit 6ffdc4d684b33777b1c483473444d25b642e0748 (HEAD -> HHH-13959, 
pdinc-oss/HHH-13959)
Author: Jason Pyeron <jpye...@pdinc.us>
Date:   Mon Apr 20 02:20:21 2020 -0400

    HHH-13959 Added optional awareness to FK driven OneToOne mappings

    * PropertyBinder needed optional awareness, null means don't change/set it

diff --git 
a/orm/hibernate-orm-5/src/test/java/org/hibernate/cfg/AnnotationBinder.java 
b/orm/hibernate-orm-5/src/test/java/org/hibernate/cfg/AnnotationBinder.java
index eec3b49..392b8c6 100644
--- a/orm/hibernate-orm-5/src/test/java/org/hibernate/cfg/AnnotationBinder.java
+++ b/orm/hibernate-orm-5/src/test/java/org/hibernate/cfg/AnnotationBinder.java
@@ -3240,6 +3240,7 @@ public final class AnnotationBinder {
                }
                else {
                        //has a FK on the table
+                       propertyBinder.setOptional(optional);
                        bindManyToOne(
                                        cascadeStrategy, joinColumns, optional, 
ignoreNotFound, cascadeOnDelete,
                                        targetEntity,
diff --git 
a/orm/hibernate-orm-5/src/test/java/org/hibernate/cfg/annotations/PropertyBinder.java
 
b/orm/hibernate-orm-5/src/test/java/org/hibernate/cfg/annotations/PropertyBinder.java
index 83c3f0c..e30946d 100644
--- 
a/orm/hibernate-orm-5/src/test/java/org/hibernate/cfg/annotations/PropertyBinder.java
+++ 
b/orm/hibernate-orm-5/src/test/java/org/hibernate/cfg/annotations/PropertyBinder.java
@@ -74,6 +74,17 @@ public class PropertyBinder {
        private EntityBinder entityBinder;
        private boolean isXToMany;
        private String referencedEntityName;
+       private Boolean optional;
+
+       public Boolean isOptional()
+       {
+               return optional;
+       }
+
+       public void setOptional(Boolean optional)
+       {
+               this.optional = optional;
+       }

        public void setReferencedEntityName(String referencedEntityName) {
                this.referencedEntityName = referencedEntityName;
@@ -328,6 +339,12 @@ public class PropertyBinder {

                LOG.tracev( "Cascading {0} with {1}", name, cascade );
                this.mappingProperty = prop;
+
+               if (optional != null)
+               {
+                   prop.setOptional(optional);
+               }
+
                return prop;
        }

-Jason

> -----Original Message-----
> From: hibernate-dev-boun...@lists.jboss.org 
> [mailto:hibernate-dev-boun...@lists.jboss.org]
> On Behalf Of Jason Pyeron
> Sent: Monday, April 20, 2020 1:12 AM
> To: hibernate-us...@lists.jboss.org; hibernate-dev@lists.jboss.org
> Subject: Re: [hibernate-dev] HHH-13959 - OneToOne JoinTable with unique 
> constraints work
> around?
> 
> [pardon the top post, it did not mix in well]
> 
> It looks like [stack trace 1] the option is never set in this situation, 
> because the only
> place it is set is when
> 
>               if ( trueOneToOne || mapToPK || 
> !BinderHelper.isEmptyAnnotationValue( mappedBy )
> ) {
> 
> but since there is a FK involved it is running
> 
>                       //has a FK on the table
>                       bindManyToOne(
>                                       cascadeStrategy, joinColumns, optional, 
> ignoreNotFound,
> cascadeOnDelete,
>                                       targetEntity,
>                                       propertyHolder, inferredData, true, 
> isIdentifierMapper,
> inSecondPass,
>                                       propertyBinder, context
>                       );
> 
> Debugging shows the optional==true. Looking at that method, the only use of 
> optional
> parameter is
> 
>               if ( !optional ) {
>                       for ( Ejb3JoinColumn column : columns ) {
>                               column.setNullable( false );
>                       }
>               }
> 
> Which is not relevant, since optional is true. That is the last line of code 
> in
> bindOneToOne(...)
> 
> Now when the evaluation of the properties are being made to persist in the 
> EntityMetamodel
> [stack trace 2] the optional is false. As a consequence the 
> checkNullability(...) will
> fail with a PropertyValueException during the nullability check [stack trace 
> 3]:
> 
> if ( !nullability[i] && value == null ) {
>                                               //check basic level one 
> nullablilty
>                                               throw new 
> PropertyValueException(
>                                                               "not-null 
> property references a null or
> transient value",
>                                                               
> persister.getEntityName(),
>                                                               
> persister.getPropertyNames()[i]
>                                                       );
> 
>                                       }
> 
> 1:    AnnotationBinder.bindManyToOne(String, Ejb3JoinColumn[], boolean, 
> boolean, boolean,
> XClass, PropertyHolder, PropertyData, boolean, boolean, boolean, 
> PropertyBinder,
> MetadataBuildingContext) line: 3116
>       AnnotationBinder.bindOneToOne(String, Ejb3JoinColumn[], boolean, 
> FetchMode, boolean,
> boolean, XClass, PropertyHolder, PropertyData, String, boolean, boolean, 
> boolean,
> PropertyBinder, MetadataBuildingContext) line: 3243
>       AnnotationBinder.processElementAnnotations(PropertyHolder, Nullability, 
> PropertyData,
> HashMap<String,IdentifierGeneratorDefinition>, EntityBinder, boolean, 
> boolean, boolean,
> MetadataBuildingContext, Map<XClass,InheritanceState>) line: 1844
>       
> AnnotationBinder.processIdPropertiesIfNotAlready(Map<XClass,InheritanceState>,
> MetadataBuildingContext, PersistentClass, EntityBinder, PropertyHolder,
> HashMap<String,IdentifierGeneratorDefinition>, ElementsToProcess, boolean, 
> Set<String>)
> line: 975
>       AnnotationBinder.bindClass(XClass, Map<XClass,InheritanceState>,
> MetadataBuildingContext) line: 802
>       
> AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(Set<String>) 
> line: 254
>       MetadataBuildingProcess$1.processEntityHierarchies(Set<String>) line: 
> 230
>       MetadataBuildingProcess.complete(ManagedResources, BootstrapContext,
> MetadataBuildingOptions) line: 273
>       EntityManagerFactoryBuilderImpl.metadata() line: 1214
>       EntityManagerFactoryBuilderImpl.build() line: 1245
>       HibernatePersistenceProvider.createEntityManagerFactory(String, Map) 
> line: 56
>       Persistence.createEntityManagerFactory(String, Map) line: 79
>       Persistence.createEntityManagerFactory(String) line: 54
>       JPAUnitTestCase.init() line: 27
> 
> 2:    PropertyFactory.buildEntityBasedAttribute(EntityPersister, 
> SessionFactoryImplementor,
> int, Property, boolean) line: 158
>       EntityMetamodel.<init>(PersistentClass, EntityPersister, 
> SessionFactoryImplementor)
> line: 224
>       
> SingleTableEntityPersister(AbstractEntityPersister).<init>(PersistentClass,
> EntityDataAccess, NaturalIdDataAccess, PersisterCreationContext) line: 601
>       SingleTableEntityPersister.<init>(PersistentClass, EntityDataAccess,
> NaturalIdDataAccess, PersisterCreationContext) line: 125
>       NativeConstructorAccessorImpl.newInstance0(Constructor<?>, Object[]) 
> line: not
> available [native method]
>       NativeConstructorAccessorImpl.newInstance(Object[]) line: not available
>       DelegatingConstructorAccessorImpl.newInstance(Object[]) line: not 
> available
>       Constructor<T>.newInstance(Object...) line: not available
>       PersisterFactoryImpl.createEntityPersister(Class<EntityPersister>, 
> PersistentClass,
> EntityDataAccess, NaturalIdDataAccess, PersisterCreationContext) line: 96
>       PersisterFactoryImpl.createEntityPersister(PersistentClass, 
> EntityDataAccess,
> NaturalIdDataAccess, PersisterCreationContext) line: 77
>       MetamodelImpl.initialize(MetadataImplementor, 
> JpaMetaModelPopulationSetting) line:
> 181
>       SessionFactoryImpl.<init>(MetadataImplementor, SessionFactoryOptions) 
> line: 299
>       SessionFactoryBuilderImpl.build() line: 468
>       EntityManagerFactoryBuilderImpl.build() line: 1249
>       HibernatePersistenceProvider.createEntityManagerFactory(String, Map) 
> line: 56
>       Persistence.createEntityManagerFactory(String, Map) line: 79
>       Persistence.createEntityManagerFactory(String) line: 54
>       JPAUnitTestCase.init() line: 27
> 
> 3:    Nullability.checkNullability(Object[], EntityPersister,
> Nullability$NullabilityCheckType) line: 92
>       Nullability.checkNullability(Object[], EntityPersister, boolean) line: 
> 55
>       
> EntityIdentityInsertAction(AbstractEntityInsertAction).nullifyTransientReferencesIfNo
> tAlready() line: 116
>       
> EntityIdentityInsertAction(AbstractEntityInsertAction).makeEntityManaged() 
> line: 125
>       ActionQueue.addResolvedEntityInsertAction(AbstractEntityInsertAction) 
> line: 289
>       ActionQueue.addInsertAction(AbstractEntityInsertAction) line: 263
>       ActionQueue.addAction(EntityIdentityInsertAction) line: 317
>       
> DefaultPersistEventListener(AbstractSaveEventListener).addInsertAction(Object[],
> Serializable, Object, EntityPersister, boolean, EventSource, boolean) line: 
> 330
>       
> DefaultPersistEventListener(AbstractSaveEventListener).performSaveOrReplicate(Object,
> EntityKey, EntityPersister, boolean, Object, EventSource, boolean) line: 287
>       
> DefaultPersistEventListener(AbstractSaveEventListener).performSave(Object,
> Serializable, EntityPersister, boolean, Object, EventSource, boolean) line: 
> 193
>       
> DefaultPersistEventListener(AbstractSaveEventListener).saveWithGeneratedId(Object,
> String, Object, EventSource, boolean) line: 123
>       DefaultPersistEventListener.entityIsTransient(PersistEvent, Map) line: 
> 185
>       DefaultPersistEventListener.onPersist(PersistEvent, Map) line: 128
>       DefaultPersistEventListener.onPersist(PersistEvent) line: 55
>       1021082377.accept(Object, Object) line: not available
>       EventListenerGroupImpl<T>.fireEventOnEachListener(U, BiConsumer<T,U>) 
> line: 102
>       SessionImpl.firePersist(PersistEvent) line: 710
>       SessionImpl.persist(Object) line: 696
>       JPAUnitTestCase.hhh13959TestProfile() line: 43
> 
> > -----Original Message-----
> > From: hibernate-dev-boun...@lists.jboss.org [mailto:hibernate-dev-
> boun...@lists.jboss.org]
> > On Behalf Of Jason Pyeron
> > Sent: Sunday, April 19, 2020 11:18 PM
> > To: hibernate-us...@lists.jboss.org; hibernate-dev@lists.jboss.org
> > Subject: [hibernate-dev] HHH-13959 - OneToOne JoinTable with unique 
> > constraints work
> > around?
> >
> > https://hibernate.atlassian.net/browse/HHH-13959
> >
> >
> >
> > I started a DB migration today, now we are dead in the water due to this 
> > exception.
> >
> >
> >
> > When I persist an Entity on the owning side of the OneToOne(optional=true) 
> > relationship,
> > and that property is null we are getting:
> >
> >
> >
> > javax.persistence.PersistenceException: 
> > org.hibernate.PropertyValueException: not-null
> > property references a null or transient value
> >
> >
> >
> > I am looking to where I can patch Hibernate or put a workaround in our code.
> >
> >
> >
> > Any help?
> >
> >
> >
> > -Jason
> >
> > _______________________________________________
> > hibernate-dev mailing list
> > hibernate-dev@lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/hibernate-dev
> 
> 
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev@lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev


_______________________________________________
hibernate-dev mailing list
hibernate-dev@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/hibernate-dev

Reply via email to