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

PgDatabaseMetaData#getImportedExportedKeys does not return partitioned indicies #2078

Closed
gallyamb opened this issue Mar 2, 2021 · 8 comments
Assignees

Comments

@gallyamb
Copy link

gallyamb commented Mar 2, 2021

Describe the issue
When you have a partitioned table with a foreign key, which in turn backed by foreign keys on concrete partitions, which is the hibernate entity's mapping, and that entity defines the same foreign key, hibernate unable to detect that such index already exists, because method in subj returns only pkic.relkind = 'i', but not pkic.relkind = 'I', that refers to partitioned index

Driver Version?
42.2.9 (but I've looked for that class on master, it have the same issue)

Java Version?
11.0.8

OS Version?
Ubuntu 18.04.5 LTS

PostgreSQL Version?
PostgreSQL 13.1 (Ubuntu 13.1-1.pgdg18.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0, 64-bit

To Reproduce

CREATE TABLE referenced (
    id character varying(255) NOT NULL PRIMARY KEY
)
PARTITIONED BY RANGE (id);
@Entity
public class Referenced {
    @Id
    public long id;
}

@Entity
public class Referencing {
    @Id
    public long id;

    @JoinColumn(
        name = "referenced",
        foreignKey = @ForeignKey(name = "fk_existing")
    )
    public Referenced referenced;
}

Expected behaviour
I'm expecting that existing foreign key does not attempted to be created

Actual behaviour
But that FK is tried to be created by Hibernate, and then PostgreSQL throws an error, that such FK already exists

Logs

Hibernate stacktrace ``` [2021-03-02 14:59:30,189] WARN [main] o.h.t.s.i.ExceptionHandlerLoggedImpl:27 GenerationTarget encountered exception accepting command : Error executing DDL "alter table if exists tbl_entity add constraint fk_entity_referenced foreign key (referenced) references tbl_referenced" via JDBC Statement org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "alter table if exists tbl_entity add constraint fk_entity_referenced foreign key (referenced) references tbl_referenced" via JDBC Statement at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlString(AbstractSchemaMigrator.java:559) at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applySqlStrings(AbstractSchemaMigrator.java:504) at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.applyForeignKeys(AbstractSchemaMigrator.java:433) at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.performMigration(AbstractSchemaMigrator.java:249) at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:114) at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:184) at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:73) at org.hibernate.internal.SessionFactoryImpl.(SessionFactoryImpl.java:316) at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:469) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:708) at my.company.name.x.db.hibernate.impl.HibernateInitializer.buildInLockAndTx(HibernateInitializer.java:127) at my.company.name.x.db.hibernate.impl.HibernateInitializer.lambda$buildInLock$2(HibernateInitializer.java:103) at my.company.name.x.tx.TxService.doCall(TxService.java:175) at my.company.name.x.tx.TxService.lambda$doInNewTx$6(TxService.java:128) at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) at my.company.name.x.tx.TxService.doInNewTx(TxService.java:128) at my.company.name.x.db.hibernate.impl.HibernateInitializer.buildInLock(HibernateInitializer.java:103) at my.company.name.x.db.hibernate.impl.HibernateInitializer.lambda$build$0(HibernateInitializer.java:87) at my.company.name.x.lock.impl.DbLockService.doInLock(DbLockService.java:204) at my.company.name.x.db.hibernate.impl.HibernateInitializer.lambda$build$1(HibernateInitializer.java:86) at my.company.name.util.Exceptions$TrashSupplier.get(Exceptions.java:105) at my.company.name.util.Exceptions.wrapRuntimeException(Exceptions.java:18) at my.company.name.x.db.hibernate.impl.HibernateInitializer.build(HibernateInitializer.java:86) at my.company.name.x.db.hibernate.impl.HibernateInitializer.build(HibernateInitializer.java:38) at my.company.name.x.y.YServiceImpl.doReload(MetaInfoServiceImpl.java:321) at my.company.name.x.y.YServiceImpl.lambda$reload$4(MetaInfoServiceImpl.java:221) at my.company.name.util.Exceptions$TrashRunnable.run(Exceptions.java:89) at my.company.name.util.Exceptions.wrapRuntimeException(Exceptions.java:22) at my.company.name.x.y.YServiceImpl.reload(MetaInfoServiceImpl.java:213) at my.company.name.x.y.YServiceImpl.reload(MetaInfoServiceImpl.java:204) at my.company.name.x.y.YServiceImpl.lambda$init$5(MetaInfoServiceImpl.java:249) at my.company.name.x.tx.TxService.lambda$runInNewTx$9(TxService.java:148) at my.company.name.x.tx.TxService.doCall(TxService.java:175) at my.company.name.x.tx.TxService.lambda$doInNewTx$8(TxService.java:143) at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) at my.company.name.x.tx.TxService.doInNewTx(TxService.java:143) at my.company.name.x.tx.TxService.runInNewTx(TxService.java:147) at my.company.name.x.y.YServiceImpl.init(MetaInfoServiceImpl.java:249) 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.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:389) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:333) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:157) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:416) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1788) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1287) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:885) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:789) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:228) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1358) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1287) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:885) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:789) at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:228) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1358) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) at my.company.name.Server.main(Server.java:21) Caused by: org.postgresql.util.PSQLException: ERROR: constraint "fk_entity_referenced" for relation "tbl_entity" already exists at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2505) at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2241) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:310) at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:447) at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:368) at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:309) at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:295) at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:272) at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:267) at jdk.internal.reflect.GeneratedMethodAccessor275.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.postgresql.ds.PGPooledConnection$StatementHandler.invoke(PGPooledConnection.java:428) at com.sun.proxy.$Proxy95.execute(Unknown Source) at my.company.name.x.db.impl.jdbc.delegates.DelegateStatement.execute(DelegateStatement.java:88) at jdk.internal.reflect.GeneratedMethodAccessor275.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at net.ttddyy.dsproxy.proxy.StatementProxyLogic.performQueryExecutionListener(StatementProxyLogic.java:316) at net.ttddyy.dsproxy.proxy.StatementProxyLogic.access$700(StatementProxyLogic.java:37) at net.ttddyy.dsproxy.proxy.StatementProxyLogic$1.execute(StatementProxyLogic.java:123) at net.ttddyy.dsproxy.listener.MethodExecutionListenerUtils.invoke(MethodExecutionListenerUtils.java:42) at net.ttddyy.dsproxy.proxy.StatementProxyLogic.invoke(StatementProxyLogic.java:120) at net.ttddyy.dsproxy.proxy.jdk.StatementInvocationHandler.invoke(StatementInvocationHandler.java:34) at com.sun.proxy.$Proxy53.execute(Unknown Source) at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:54) ... 88 common frames omitted ```
@davecramer
Copy link
Member

Good catch. Thanks!

@davecramer davecramer self-assigned this Mar 2, 2021
davecramer added a commit to davecramer/pgjdbc that referenced this issue Mar 3, 2021
@davecramer
Copy link
Member

So looking at this. This table above does not create a foreign key, It does create a partitioned primary key which we failed to find. see #2087 and let me know if that fixes your problem

@gallyamb
Copy link
Author

gallyamb commented Mar 4, 2021

Maybe I'm not accurate in usage of terms, my bad. I'll try that fix and come back with feedback. Thank you so much!

davecramer added a commit that referenced this issue Mar 8, 2021
* fix: Partitioned indexes were not found fixes (#2078)
davecramer added a commit to davecramer/pgjdbc that referenced this issue Mar 8, 2021
davecramer added a commit that referenced this issue Mar 9, 2021
* fix: Partitioned indexes were not found fixes (#2078) (#2087)
@gallyamb
Copy link
Author

Yes, that commit fixes the issue. Thank you!

@gallyamb
Copy link
Author

@davecramer What should I do for that fix being merged?

@davecramer
Copy link
Member

@gallyamb it has been merged

@gallyamb
Copy link
Author

Thanks! Can I close the issue now? Or it will be closed when new version released?

@davecramer
Copy link
Member

davecramer commented Mar 18, 2021 via email

jorsol pushed a commit to jorsol/pgjdbc that referenced this issue Oct 12, 2021
davecramer added a commit that referenced this issue Oct 12, 2021
* fix: Partitioned indexes were not found fixes (#2078)

Co-authored-by: Dave Cramer <davecramer@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants