Is name and referencedColumnName both needed in @JoinColumn

Is name and referencedColumnName both needed in @JoinColumn. Can I only use name variable and be ok with it?

Example:

ManyToOne(fetch = FetchType.LAZY)
JsonBackReference
@JoinColumn(name=apl_id, referencedColumnName=apl_id, nullable=false, insertable = false, updatable = false)
private TestObject testObject;

Asking this question here, because removing referencedColumnName is helping us resolve the shared reference error. See error below.

Search Query Processing error org.springframework.orm.jpa.JpaSystemException: Found shared references to a collection:

Wanted to understand in details why this change is helping resolve the shared reference issue so that we do not run in surprises down the line.

Note: We are using 5.4.25.Final hibernate version.

Of course, you don’t have to explicitly specify the referencedColumnName attribute for a @JoinColumn as that is an optional member of the annotation. By default, the join column will reference the primary key column of the associated table. You can find more details on the JPA annotation’s javadoc.

As for the query processing error you’re seeing, it seems to come from Spring framework and I would need to see the full stack trace to understand if it’s triggered by Hibernate, so I’m afraid I can’t help you with that unless you share it.

Thank You mdladel for taking a look at this. For more understanding of this error see below the full stack trace.

org.springframework.orm.jpa.JpaSystemException: Found shared references to a collection: com.some.common.SomeObject.childObjects; nested exception is org.hibernate.HibernateException: Found shared references to a collection: com.some.common.SomeObject.childObjects
	at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:353)
	at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:255)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:531)
	at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
	at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:154)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:149)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:322)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
	at org.springframework.boot.loader.Launcher.launch(Launcher.java:107)
	at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
	at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:59)
Caused by: org.hibernate.HibernateException: Found shared references to a collection: com.some.common.SomeObject.childObjects
	at org.hibernate.engine.internal.Collections.processReachableCollection(Collections.java:188)
	at org.hibernate.event.internal.FlushVisitor.processCollection(FlushVisitor.java:50)
	at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:104)
	at org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:65)
	at org.hibernate.event.internal.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:59)
	at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:184)
	at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:232)
	at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:92)
	at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:50)
	at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102)
	at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1327)
	at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1407)
	at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1625)
	at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1593)
	at org.hibernate.query.Query.getResultList(Query.java:165)
	at org.springframework.data.jpa.repository.query.JpaQueryExecution$CollectionExecution.doExecute(JpaQueryExecution.java:126)
	at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:88)
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:154)
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:142)
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor$QueryMethodInvoker.invoke(QueryExecutorMethodInterceptor.java:195)
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:152)
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:367)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)

That error usually happens with incorrect mappings that lead to circularities or shared reference between/to collections. I would need to see the complete mappings to understand more specifically what’s going on, but I suspect you might be doing something wrong when setting referencedColumnName (seeing as you were setting both to apl_id you might be referencing a foreign key with itself).

Note that in @JoinColumn, the name member specifies the name of the foreign key column on the association owner’s table, while referencedColumnName indicates the name of the column on the association target’s table which is the target of said foreign key.

1 Like