2017-01-09 87 views
0

我得到嘗試部署使用Hibernate的應用程序時出現以下錯誤主鍵:休眠引用不存在

外鍵(FK2e496501ee5lgk3viylwiicsa:MANAGED_APP_TO_CON_TO_SRUCT [MANAGED_APP_TO_CONTACT_ID]))必須具有相同數量作爲被引用的主鍵(MANAGED_APPLICATION_TO_CONTACT [CONTACT_ID,MANAGED_APPLICATION_ID])

但列的我不知道按什麼鍵休眠這裏引用。正如您從Oracle SQL Developer生成的模型中可以看到的那樣,CONTACT_ID, MANAGED_APPLICATION_ID上沒有複合主鍵。 MANAGED_APPLICATION_TO_CONTACT的主鍵位於已排序的列MANAGED_APP_TO_CONTACT_ID上,該列是外鍵中引用的列。

enter image description here

所以,我認爲,導致這一問題就在於我的實體JPA映射的地方。下面是相關實體(請注意,我選擇發佈完整的實體,而不是一個最小的例子,如果問題在於地方,我不會在我的實體期待):

ManagedApplicationToContact:

@Entity 
@Table(name = "MANAGED_APPLICATION_TO_CONTACT", schema = "UAM") 
public class ManagedApplicationToContact implements java.io.Serializable { 


    private Long managedAppToContactId; 
    private ManagedApplication managedApplication; 
    private Contact contact; 
    private Long lastUpdatedBy; 
    private Date lastUpdated; 

    public ManagedApplicationToContact() { 
    } 

    public ManagedApplicationToContact(final ManagedApplication managedApplication, final Contact contact, final Long lastUpdatedBy, final Date lastUpdated) { 
     this.managedApplication = managedApplication; 
     this.contact = contact; 
     this.lastUpdatedBy = lastUpdatedBy; 
     this.lastUpdated = lastUpdated; 
    } 

    @SequenceGenerator(name = "generator", sequenceName = "UAM.SEQ_MANAGED_APP_TO_CONTACT", initialValue = 0, allocationSize = 1) 
    @Id 
    @GeneratedValue(strategy = SEQUENCE, generator = "generator") 
    @Column(name = "MANAGED_APP_TO_CONTACT_ID", unique = true, nullable = false, precision = 15, scale = 0) 
    public Long getManagedAppToContactId() { 
     return this.managedAppToContactId; 
    } 

    public void setManagedAppToContactId(final Long managedAppToContactId) { 
     this.managedAppToContactId = managedAppToContactId; 
    } 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "MANAGED_APPLICATION_ID", nullable = false) 
    public ManagedApplication getManagedApplication() { 
     return this.managedApplication; 
    } 

    public void setManagedApplication(final ManagedApplication managedApplication) { 
     this.managedApplication = managedApplication; 
    } 

    @Column(name = "LAST_UPDATED_BY", nullable = false, precision = 15, scale = 0) 
    public Long getLastUpdatedBy() { 
     return this.lastUpdatedBy; 
    } 

    public void setLastUpdatedBy(final Long lastUpdatedBy) { 
     this.lastUpdatedBy = lastUpdatedBy; 
    } 

    @Temporal(TemporalType.TIMESTAMP) 
    @Column(name = "LAST_UPDATED", length = 7) 
    public Date getLastUpdated() { 
     return this.lastUpdated; 
    } 

    public void setLastUpdated(final Date lastUpdated) { 
     this.lastUpdated = lastUpdated; 
    } 

    @ManyToOne 
    @JoinColumn(name= "CONTACT_ID", referencedColumnName = "CONTACT_ID", nullable = false) 
    public Contact getContact() { 
     return contact; 
    } 

    public void setContact(final Contact contact) { 
     this.contact = contact; 
    } 
} 

ManagedAppToConToStruct:

@Entity 
@Table(name = "MANAGED_APP_TO_CON_TO_STRUCT", schema = "UAM") 
public class ManagedAppToConToStruct { 
    @SequenceGenerator(name = "generator", sequenceName = "UAM.MAN_APP_TO_CON_TO_STRUCT_SEQ", allocationSize = 1) 

    @Id 
    @GeneratedValue(strategy = SEQUENCE, generator = "generator") 
    @Column(name = "ID", unique = true, nullable = false) 
    private Long id; 

    @ManyToOne 
    @JoinColumn(name= "MANAGED_APP_TO_CONTACT_ID", referencedColumnName = "MANAGED_APP_TO_CONTACT_ID", nullable = false) 
    private ManagedApplicationToContact managedApplicationToContact; 

    @ManyToOne 
    @JoinColumn(name="STRUCTURE_ID", nullable = false) 
    private Structure structure; 

    @Column(name = "LAST_UPDATED") 
    private LocalDateTime lastUpdated; 

    @Column(name = "LAST_UPDATED_BY") 
    @Basic 
    private Long lastUpdatedBy; 

    public Long getId() { 
     return id; 
    } 

    public void setId(final Long id) { 
     this.id = id; 
    } 

    public ManagedApplicationToContact getManagedApplicationToContact() { 
     return managedApplicationToContact; 
    } 

    public void setManagedApplicationToContact(final ManagedApplicationToContact managedApplicationToContact) { 
     this.managedApplicationToContact = managedApplicationToContact; 
    } 

    public Structure getStructure() { 
     return structure; 
    } 

    public void setStructure(final Structure structure) { 
     this.structure = structure; 
    } 

    public LocalDateTime getLastUpdated() { 
     return lastUpdated; 
    } 

    public void setLastUpdated(final LocalDateTime lastUpdated) { 
     this.lastUpdated = lastUpdated; 
    } 

    public Long getLastUpdatedBy() { 
     return lastUpdatedBy; 
    } 

    public void setLastUpdatedBy(final Long lastUpdatedBy) { 
     this.lastUpdatedBy = lastUpdatedBy; 
    } 
} 

我甚至用過的IntelliJ IDE內置的實體生成功能建立在t這些實體他數據庫模式,並且它產生了相同的映射。我爲我的項目添加了一個Hibernate JPA構面,IntelliJ指出所有的映射都是正確的 - 所以我在這裏嚴重受難了。


編輯:添加創建表的語句。

MANAGED_APPLICATION_TO_CONTACT:(這個是從Oracle SQL Developer中產生的,因爲我沒有已運行原始腳本)

CREATE TABLE "UAM"."MANAGED_APPLICATION_TO_CONTACT" 
    ( "MANAGED_APP_TO_CONTACT_ID" NUMBER(15,0) NOT NULL ENABLE, 
    "CONTACT_ID" NUMBER(15,0) NOT NULL ENABLE, 
    "MANAGED_APPLICATION_ID" NUMBER(6,0) NOT NULL ENABLE, 
    "LAST_UPDATED_BY" NUMBER, 
    "LAST_UPDATED" DATE, 
    CONSTRAINT "MANAGE_APPLICATION_CONTACT_PK" PRIMARY KEY ("MANAGED_APP_TO_CONTACT_ID") 
    USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 
    BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 
    TABLESPACE "UAM" ENABLE, 
    CONSTRAINT "MANAGED_APPLICATION_TO_CO_FK1" FOREIGN KEY ("MANAGED_APPLICATION_ID") 
     REFERENCES "UAM"."MANAGED_APPLICATION" ("MANAGED_APPLICATION_ID") ENABLE 
    ) SEGMENT CREATION IMMEDIATE 
    PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
NOCOMPRESS LOGGING 
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 
    BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT) 
    TABLESPACE "UAM" ; 

MANAGED_APP_TO_CON_TO_STRUCT:(這是實際的腳本是用於創建表)

CREATE TABLE UAM.MANAGED_APP_TO_CON_TO_STRUCT (
    ID NUMBER NOT NULL, 
    MANAGED_APP_TO_CONTACT_ID NUMBER(15) NOT NULL, 
    STRUCTURE_ID NUMBER NOT NULL, 
    LAST_UPDATED TIMESTAMP(6) DEFAULT SYSTIMESTAMP NOT NULL, 
    LAST_UPDATED_BY NUMBER NOT NULL, 
    CONSTRAINT MAN_APP_TO_CON_TO_STRUCT_PK PRIMARY KEY (ID), 
    CONSTRAINT MAN_APP_TO_CON_TO_STRUCT_FK01 FOREIGN KEY (MANAGED_APP_TO_CONTACT_ID) REFERENCES UAM.MANAGED_APPLICATION_TO_CONTACT (MANAGED_APP_TO_CONTACT_ID), 
    CONSTRAINT MAN_APP_TO_CON_TO_STRUCT_FK02 FOREIGN KEY (STRUCTURE_ID) REFERENCES HIERARCHY.STRUCTURE (STRUCTURE_ID), 
    CONSTRAINT MAN_APP_TO_CON_TO_STRUCT_FK03 FOREIGN KEY (LAST_UPDATED_BY) REFERENCES MCT.CONTACT (CONTACT_ID) 
); 
CREATE UNIQUE INDEX UAM.MAN_APP_TO_CON_TO_STRUCT_IDX01 ON UAM.MANAGED_APP_TO_CON_TO_STRUCT (MANAGED_APP_TO_CONTACT_ID, STRUCTURE_ID); 

編輯:添加完整的堆棧跟蹤。

2017-01-06 15:34:42.834 ERROR [RMI TCP Connection(5)-127.0.0.1] o.s.web.context.ContextLoader:353 - Context initialization failed 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'MCT' defined in com.myproject.JpaConfig: Invocation of init method failed; nested exception is org.hibernate.MappingException: Foreign key (FK2e496501ee5lgk3viylwiicsa:MANAGED_APP_TO_CON_TO_STRUCT [MANAGED_APP_TO_CONTACT_ID])) must have same number of columns as the referenced primary key (MANAGED_APPLICATION_TO_CONTACT [CONTACT_ID,MANAGED_APPLICATION_ID]) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1054) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:829) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) 
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:446) 
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:328) 
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107) 
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4990) 
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5490) 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) 
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) 
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) 
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:649) 
    at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1763) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:483) 
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301) 
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) 
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) 
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:618) 
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:565) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:483) 
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301) 
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) 
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) 
    at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1466) 
    at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76) 
    at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1307) 
    at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1399) 
    at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:828) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:483) 
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323) 
    at sun.rmi.transport.Transport$1.run(Transport.java:200) 
    at sun.rmi.transport.Transport$1.run(Transport.java:197) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196) 
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$240(TCPTransport.java:683) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$1/1638143133.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: org.hibernate.MappingException: Foreign key (FK2e496501ee5lgk3viylwiicsa:MANAGED_APP_TO_CON_TO_STRUCT [MANAGED_APP_TO_CONTACT_ID])) must have same number of columns as the referenced primary key (MANAGED_APPLICATION_TO_CONTACT [CONTACT_ID,MANAGED_APPLICATION_ID]) 
    at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:137) 
    at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:119) 
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.secondPassCompileForeignKeys(InFlightMetadataCollectorImpl.java:1888) 
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.secondPassCompileForeignKeys(InFlightMetadataCollectorImpl.java:1808) 
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1627) 
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278) 
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:847) 
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:874) 
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) 
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343) 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) 
    ... 58 common frames omitted 

編輯:

也想指出,ManagedApplicationToContact實體被添加ManagedAppToConToStruct前工作完全正常。

+0

您能否提供堆棧跟蹤的完整例外而不是唯一的例外消息?查看鏈中的哪個組件可以準確地發現此錯誤可能很有趣。另外:生成SQL創建語句而不是可視化圖表可能會更好。你需要對涉及的內容進行最少解釋的觀點。 – Gimby

+0

@Gimby添加stacktrace並創建語句 –

+0

通常情況下,您不應該在'SequenceGenerator'中重複使用該名稱,但這只是一個額外的問題,您稍後可能會遇到。這不是你目前的問題。我仍然期待看到缺少的東西。其他問題包括'JoinColumn'中的'referencedColumnName'應該在另一端具有字段的名稱,而不是列的sql-name。 – coladict

回答

1

所以,事實證明,我曾在Contact實體此映射是用MANAGED_APPLICATION_TO_CONTACT作爲連接表檢索ManagedApplication記錄綁在Contact,這是導致休眠承擔對CONTACT_ID,MANAGED_APPLICATION_ID主鍵:

@ManyToMany(fetch = FetchType.LAZY) 
@JoinTable(name = "MANAGED_APPLICATION_TO_CONTACT", schema = "UAM", 
     joinColumns = {@JoinColumn(name = "CONTACT_ID", 
       referencedColumnName = "CONTACT_ID", 
       nullable = false)}, 
     inverseJoinColumns = {@JoinColumn(name = "MANAGED_APPLICATION_ID", 
       referencedColumnName = "MANAGED_APPLICATION_ID", 
       nullable = false)}) 
@OrderBy("name asc") 
public Set<ManagedApplication> getManagedApplications() { 
    return this.managedApplications; 
} 

public void setManagedApplications(final Set<ManagedApplication> managedApplications) { 
    this.managedApplications = managedApplications; 
} 

爲了解決這個問題,我擺脫了這個映射,並將它變成了一個瞬態方法,它將ManagedApplication記錄從已經正確映射的managedApplicationToContacts記錄中提取出來。

@Transient 
public Set<ManagedApplication> getManagedApplications() { 
    if (this.managedApplications.isEmpty()) { 
     this.managedApplications = this.managedApplicationToContacts.stream() 
       .map(ManagedApplicationToContact::getManagedApplication) 
       .collect(Collectors.toSet()); 
    } 
    return this.managedApplications; 
}