[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