Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@UpdateableEntityView not working with Hibernate discriminator based multi-tenancy #1819

Open
kuhnroyal opened this issue Nov 2, 2023 · 1 comment
Labels

Comments

@kuhnroyal
Copy link

Description

My project uses Hibernate discriminator based multi-tenancy and reading/listing entity views works correctly, filtered by tenant.
I added my first @UpdateableEntityView and I am getting parameter count errors when trying to save them.

The problem happens here https://github.com/Blazebit/blaze-persistence/blob/main/integration/hibernate6-base/src/main/java/com/blazebit/persistence/integration/hibernate/base/HibernateExtendedQuerySupport.java#L798
There are 3 participating queries and a total of 3 parameterBinders - but the finalSql only has 2 parameters.
After checking the binders, it seems that the tenant ID filter from Hibernate is applied to more than on participating query and then added twice.

I assume this happens only when the entity view has an updatable relation but I still need to verify this.
The same update works fine when running this without multi-tenancy enabled.

The updateable view is a user with its roles.

Expected behavior

I expect @UpdateableEntityView to work in combination with Hibernate discriminator based multi-tenancy.

Actual behavior

The following exception is thrown:

Caused by: org.hibernate.exception.DataException: JDBC exception executing SQL [delete from user_roles using users_local l1_0 join users l1_1 on l1_0.id=l1_1.id left join user_roles r1_0 on l1_1.id=r1_0.user_id where l1_1.tenant_id = ? and user_roles.user_id=? and user_roles.user_id = r1_0.user_id] [Der Spaltenindex 3 ist außerhalb des gültigen Bereichs. Anzahl Spalten: 2.] [n/a]
	at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:101)
	at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:56)
	at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:108)
	at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:94)
	at org.hibernate.sql.exec.internal.StandardJdbcMutationExecutor.execute(StandardJdbcMutationExecutor.java:96)
	at com.blazebit.persistence.integration.hibernate.base.HibernateExtendedQuerySupport.executeUpdate(HibernateExtendedQuerySupport.java:866)
	at com.blazebit.persistence.impl.plan.CustomModificationQueryPlan.executeUpdate(CustomModificationQueryPlan.java:52)
	at com.blazebit.persistence.impl.query.CustomSQLQuery.executeUpdate(CustomSQLQuery.java:62)
	at com.blazebit.persistence.view.impl.update.flush.CollectionAttributeFlusher.deleteElements(CollectionAttributeFlusher.java:457)
	at com.blazebit.persistence.view.impl.update.flush.CollectionAttributeFlusher.replaceCollection(CollectionAttributeFlusher.java:1036)
	at com.blazebit.persistence.view.impl.update.flush.CollectionAttributeFlusher.replaceCollection(CollectionAttributeFlusher.java:64)
	at com.blazebit.persistence.view.impl.update.flush.AbstractPluralAttributeFlusher.invokeFlushOperation(AbstractPluralAttributeFlusher.java:291)
	at com.blazebit.persistence.view.impl.update.flush.CollectionAttributeFlusher.flushQuery(CollectionAttributeFlusher.java:286)
	at com.blazebit.persistence.view.impl.update.flush.CollectionAttributeFlusher.flushQuery(CollectionAttributeFlusher.java:64)
	at com.blazebit.persistence.view.impl.update.flush.CompositeAttributeFlusher.flushQuery(CompositeAttributeFlusher.java:448)
	at com.blazebit.persistence.view.impl.update.EntityViewUpdaterImpl.update(EntityViewUpdaterImpl.java:711)
	at com.blazebit.persistence.view.impl.update.EntityViewUpdaterImpl.executeUpdate(EntityViewUpdaterImpl.java:637)
	at com.blazebit.persistence.view.impl.EntityViewManagerImpl.update(EntityViewManagerImpl.java:1193)
	at com.blazebit.persistence.view.impl.EntityViewManagerImpl.update(EntityViewManagerImpl.java:1153)
	at com.blazebit.persistence.view.impl.EntityViewManagerImpl.save(EntityViewManagerImpl.java:1070)
	at com.blazebit.persistence.spring.data.base.repository.AbstractEntityViewAwareRepository.save(AbstractEntityViewAwareRepository.java:170)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	at java.base/java.lang.reflect.Method.invoke(Method.java:578)
	at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:288)
	at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:136)
	at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:120)
	at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:516)
	at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:628)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:168)
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:72)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at com.blazebit.persistence.spring.data.repository.EntityViewReplacingMethodInterceptor.invoke(EntityViewReplacingMethodInterceptor.java:52)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:391)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
	... 219 common frames omitted
Caused by: org.postgresql.util.PSQLException: Der Spaltenindex 3 ist außerhalb des gültigen Bereichs. Anzahl Spalten: 2.
	at org.postgresql.core.v3.SimpleParameterList.bind(SimpleParameterList.java:70)
	at org.postgresql.core.v3.SimpleParameterList.setBinaryParameter(SimpleParameterList.java:137)
	at org.postgresql.jdbc.PgPreparedStatement.bindBytes(PgPreparedStatement.java:1087)
	at org.postgresql.jdbc.PgPreparedStatement.setUuid(PgPreparedStatement.java:1662)
	at org.postgresql.jdbc.PgPreparedStatement.setObject(PgPreparedStatement.java:986)
	at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.setObject(HikariProxyPreparedStatement.java)
	at org.hibernate.type.descriptor.jdbc.UUIDJdbcType$1.doBind(UUIDJdbcType.java:65)
	at org.hibernate.type.descriptor.jdbc.BasicBinder.bind(BasicBinder.java:61)
	at org.hibernate.internal.FilterJdbcParameter.bindParameterValue(FilterJdbcParameter.java:39)
	at org.hibernate.sql.exec.internal.StandardJdbcMutationExecutor.execute(StandardJdbcMutationExecutor.java:73)
	... 256 common frames omitted

Steps to reproduce

Will try to create a sample later somehow.

Environment

Version: 1.6.9
JPA-Provider: Hibernate 6.2.13.Final
DBMS: PostgreSQL
Application Server: Java/Spring 6

@beikov
Copy link
Member

beikov commented Nov 3, 2023

Hi there, like I posted on the other issue you created, please create a reproducer for this based on the quickstart:

mvn archetype:generate "-DarchetypeGroupId=com.blazebit" "-DarchetypeArtifactId=blaze-persistence-archetype-entity-view-sample-jakarta" "-DarchetypeVersion=1.6.9"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants