[hibernate-dev] HHH-13959 - OneToOne JoinTable with unique constraints work around?

Jason Pyeron jpyeron at pdinc.us
Mon Apr 20 01:12:23 EDT 2020


[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).nullifyTransientReferencesIfNotAlready() 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 at lists.jboss.org [mailto:hibernate-dev-bounces at lists.jboss.org]
> On Behalf Of Jason Pyeron
> Sent: Sunday, April 19, 2020 11:18 PM
> To: hibernate-users at lists.jboss.org; hibernate-dev at 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 at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev




More information about the hibernate-dev mailing list