[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 <jpyeron(a)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-bounces(a)lists.jboss.org
[mailto:hibernate-dev-bounces@lists.jboss.org]
On Behalf Of Jason Pyeron
Sent: Monday, April 20, 2020 1:12 AM
To: hibernate-users(a)lists.jboss.org; hibernate-dev(a)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-bounces(a)lists.jboss.org [mailto:hibernate-dev-
bounces(a)lists.jboss.org]
> On Behalf Of Jason Pyeron
> Sent: Sunday, April 19, 2020 11:18 PM
> To: hibernate-users(a)lists.jboss.org; hibernate-dev(a)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(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/hibernate-dev
_______________________________________________
hibernate-dev mailing list
hibernate-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/hibernate-dev