I applied the patch to b897a36f2f. The only new test failure I encountered was org.hibernate.test.annotations.cascade.NonNullableCircularDependencyCascadeTest
testIdClassInSuperclass javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154) at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181) at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188) at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1356) at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1339) at org.hibernate.test.annotations.cascade.NonNullableCircularDependencyCascadeTest.testIdClassInSuperclass(NonNullableCircularDependencyCascadeTest.java:42) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.hibernate.testing.junit4.ExtendedFrameworkMethod.invokeExplosively(ExtendedFrameworkMethod.java:45) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:298) at org.junit.internal.runners.statements.FailOnTimeout$CallableStatement.call(FailOnTimeout.java:292) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.lang.Thread.run(Thread.java:748) Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:109) at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3235) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3760) at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:107) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478) at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475) at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:348) at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40) at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102) at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1352) ... 17 more Caused by: org.h2.jdbc.JdbcSQLException: NULL not allowed for column "DEFAULTCHILDID"; SQL statement: insert into Parent (defaultChildId, id) values (?, ?) [23502-196] at org.h2.message.DbException.getJdbcSQLException(DbException.java:345) at org.h2.message.DbException.get(DbException.java:179) at org.h2.message.DbException.get(DbException.java:155) at org.h2.table.Column.validateConvertUpdateSequence(Column.java:345) at org.h2.table.Table.validateConvertUpdateSequence(Table.java:797) at org.h2.command.dml.Insert.insertRows(Insert.java:151) at org.h2.command.dml.Insert.update(Insert.java:114) at org.h2.command.CommandContainer.update(CommandContainer.java:101) at org.h2.command.Command.executeUpdate(Command.java:260) at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:164) at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:150) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197) ... 28 more > -----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 2:25 AM > To: hibernate-dev@lists.jboss.org > Subject: Re: [hibernate-dev] HHH-13959 - OneToOne JoinTable with unique > constraints work > around? > > [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 _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev