hibernate referencedColumnNames未映射到单个属性

我在使用Hibernate 4的spring 3 Web应用程序中获得以下exception:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mySessionFactory' defined in URL [file:war/WEB-INF/datasource-config.xml]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: referencedColumnNames(DISCUSSION_ID) of com.jr.freedom.discusion.Message.discussion referencing com.jr.freedom.discusion.Discussion not mapped to a single property at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:567) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464) at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:96) at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:44) at org.springframework.test.context.TestContext.buildApplicationContext(TestContext.java:198) at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:233) at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:126) at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:85) at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:231) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:95) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:139) at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51) at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44) at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27) at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37) at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) Caused by: org.hibernate.AnnotationException: referencedColumnNames(DISCUSSION_ID) of com.jr.freedom.discusion.Message.discussion referencing com.jr.freedom.discusion.Discussion not mapped to a single property at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:205) at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:116) at org.hibernate.cfg.Configuration.processEndOfQueue(Configuration.java:1514) at org.hibernate.cfg.Configuration.processFkSecondPassInOrder(Configuration.java:1437) at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1355) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1724) at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1775) at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.java:184) at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:314) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452) ... 29 more 

下面是使用丢弃Pojo的消息POJO:

 @Entity @Table(name = "MESSAGE") public class Message { @Id @Column(name = "message_id") private String id; @Column(name = "message_text", nullable = false) private String messageText; /** * Foreign key for user table */ @Id @OneToOne @JoinColumn(name = "from_user", nullable = false) private User fromUser; /** * Foreign key for discussion table */ @Id @ManyToOne @JoinColumn(name = "discussion",referencedColumnName="DISCUSSION_ID", nullable = false) private Discussion discussion; public Message() { id = UUID.randomUUID().toString(); } public String getMessageText() { return messageText; } public void setMessageText(String messageText) { this.messageText = messageText; } public User getFromUser() { return fromUser; } public void setFromUser(User fromUser) { this.fromUser = fromUser; } public Discussion getDiscussionId() { return discussion; } public void setDiscussionId(Discussion discussion) { this.discussion = discussion; } public String getId() { return id; } } 

这是讨论POJO:

 @Entity @Table(name = "DISCUSSION") public class Discussion { @Id @Column(name = "DISCUSSION_ID") private String id; @Column(name = "TITLE", nullable = false) private String title; @Column(name = "CATAGORY", nullable = false) private String catagory; @Id @OneToOne @JoinColumn(name = "discussionOwner", nullable = false) private User discussionOwner; public Discussion() { id = UUID.randomUUID().toString(); } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getCatagory() { return catagory; } public void setCatagory(String catagory) { this.catagory = catagory; } public User getDiscussionOwner() { return discussionOwner; } public void setDiscussionOwner(User discussionOwner) { this.discussionOwner = discussionOwner; } public String getId() { return id; } } 

我错过了什么? 这两个实体之间的关系是讨论实体可以包含许多消息,而消息只能属于一个讨论

提前致谢

对于那些有兴趣进行复合键连接的人,请尝试:

 @JoinColumns({ @JoinColumn(name = "x", referencedColumnName = "x"), @JoinColumn(name = "y", referencedColumnName = "y"), @JoinColumn(name = "z", referencedColumnName = "z") }) 

基本上,如果您有3列标记为@ID,则JPA假定您需要所有3列才能获得唯一标识。 这意味着在外键侧,您还需要3列来进行正确的外键引用。