2013-02-24 64 views
0

我有一個袋鼠腳本行是這樣的:爲什麼需要關係表從實體到同一實體

字段設置--class會員--fieldName invitedby --type會員--cardinality ONE_TO_MANY

Hibernate的要求與列成員和invitedby一個名爲member_invitedby表:

PersistenceException: [PersistenceUnit: megaadmin] Unable to build EntityManagerFactory 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1486) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461) 
     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) 
     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) 
     at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) 
     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
     at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1117) 
     at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:922) 
     at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) 
     at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:383) 
     at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283) 
     at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112) 
     at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4791) 
     at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5285) 
     at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) 
     at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559) 
     at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549) 
     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:166) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 
     at java.lang.Thread.run(Thread.java:722) 
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: megaadmin] Unable to build EntityManagerFactory 
     at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:915) 
     at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:890) 
     at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:74) 
     at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:286) 
     at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1545) 
     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1483) 
     ... 22 more 
Caused by: org.hibernate.HibernateException: Missing table: member_invitedby 
     at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1272) 
     at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:155) 
     at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:506) 
     at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1750) 
     at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:94) 
     at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:905) 
     ... 28 more 

如果我manualy創建一個列成員和invitedby表member_invitedby此異常消失。

我不知道爲什麼hibernate需要一個n-m表,因爲一個成員只能由一個成員邀請,它是一個1-n!

問候。

回答

1

映射OneToMany單向關聯的默認方式是使用連接表。這避免了在連接列中污染兒童(許多),因爲它不應該知道其父(一邊)。

如果你想在很多方面引用一個外鍵,那麼你需要在OneToMany關聯聲明中明確地使用@JoinColumn標註來說明。如何與Roo做到這一點,我不知道。

+0

沿着我的個人概念:很少有人認爲自我1-n不是實體s.o的存在的一部分。污染兒童s.o.它是一個反模式。嘿,你可以請一個具體的例子來解釋一下當一個孩子污染了嗎? – 2013-02-25 06:44:59

+0

假設你有一個用戶和一個地址。用戶有多個地址。但辦事處也有地址。公司也有地址。和聯繫人也有地址。地址不需要知道它們是否適用於用戶,辦公室,公司或聯繫人。所以協會在任何情況下都是單向的一對多協會。您不希望地址表中有4個外鍵來執行此操作。如果您將一個提供程序添加到具有地址的一組實體中,則不希望在地址表中添加另一個可爲空的外鍵。在這種情況下,連接表是更好的選擇。 – 2013-02-25 08:10:41

+0

續:至少這是JPA規範認爲的,因此他們決定在單向一對多關聯的情況下將其設置爲默認值。但是,如果您更喜歡使用joi列映射關聯,則他們可以通過將JoinColumn註釋添加到關聯來讓您做出其他選擇。如果關聯是雙向的,則默認是使用連接列。 – 2013-02-25 08:12:40