我在使用Hibernate 4的春季3 Web应用程序中获得以下异常:
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;
}
}
我缺少什么?这两个实体之间的关系是讨论实体可以包含许多消息,而消息只能属于一个讨论
提前致谢
答案 0 :(得分:16)
对于那些有兴趣进行复合键连接的人,请尝试:
@JoinColumns({
@JoinColumn(name = "x", referencedColumnName = "x"),
@JoinColumn(name = "y", referencedColumnName = "y"),
@JoinColumn(name = "z", referencedColumnName = "z")
})
基本上,如果您有3列标记为@ID,则JPA假定您需要所有3列才能获得唯一标识。这意味着在外键方面,您还需要3列来进行正确的外键引用。