2017-10-11 50 views
0

我見過很多關於繼承的帖子,但沒有任何符合我的問題。JPA繼承與聯合戰略

我嘗試建立一個正確的對象模型:

的根類

@Entity 
@Inheritance(strategy = InheritanceType.JOINED) 
public abstract class Identity { 

    @Id 
    @GeneratedValue 
    public long id; 

} 

一箇中間類

@Entity 
public class Group extends Identity { 

    @ManyToMany 
    public Collection<Identity> identities = new HashSet<>(); 

} 

其他兩個類,一個是從Group繼承和其他從Identity

@Entity 
public class Abonne extends Group {} 

@Entity 
public class User extends Identity {} 

我使用springboot 1.5.2和一個mysql數據庫。我已經有了一些具有相同配置的應用程序,但這是我第一次嘗試這種繼承模型。

當我運行springboot,它在創建表時推出例外:

org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.5.2.RELEASE:run (default-cli) on project mova.pcp: An exception occurred while running. null 
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:212) 
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153) 
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145) 
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116) 
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80) 
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51) 
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128) 
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307) 
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193) 
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106) 
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:863) 
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288) 
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:199) 
    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:497) 
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289) 
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229) 
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415) 
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356) 
    at org.codehaus.classworlds.Launcher.main(Launcher.java:47) 
Caused by: org.apache.maven.plugin.MojoExecutionException: An exception occurred while running. null 
    at org.springframework.boot.maven.AbstractRunMojo$IsolatedThreadGroup.rethrowUncaughtException(AbstractRunMojo.java:495) 
    at org.springframework.boot.maven.RunMojo.runWithMavenJvm(RunMojo.java:95) 
    at org.springframework.boot.maven.AbstractRunMojo.run(AbstractRunMojo.java:249) 
    at org.springframework.boot.maven.AbstractRunMojo.execute(AbstractRunMojo.java:181) 
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134) 
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207) 
    ... 21 more 
Caused by: java.lang.reflect.InvocationTargetException 
    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:497) 
    at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:527) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) 
    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:1081) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:856) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) 
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) 
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) 
    at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:134) 
    at alfresco.less.Config.main(Config.java:16) 
    ... 6 more 
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory 
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:954) 
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:882) 
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) 
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353) 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:370) 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:359) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) 
    ... 21 more 
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Unable to execute schema management to JDBC target [create table group (id bigint not null, primary key (id))] 
    at org.hibernate.tool.schema.internal.TargetDatabaseImpl.accept(TargetDatabaseImpl.java:59) 
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applySqlString(SchemaMigratorImpl.java:431) 
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applySqlStrings(SchemaMigratorImpl.java:420) 
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.createTable(SchemaMigratorImpl.java:236) 
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigrationToTargets(SchemaMigratorImpl.java:167) 
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:60) 
    at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:134) 
    at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:101) 
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:472) 
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444) 
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879) 
    ... 27 more 
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'group (id bigint not null, primary key (id))' at line 1 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422) 
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) 
    at com.mysql.jdbc.Util.getInstance(Util.java:408) 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:943) 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973) 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909) 
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527) 
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680) 
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2497) 
    at com.mysql.jdbc.StatementImpl.executeUpdateInternal(StatementImpl.java:1540) 
    at com.mysql.jdbc.StatementImpl.executeLargeUpdate(StatementImpl.java:2595) 
    at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1468) 
    at org.hibernate.tool.schema.internal.TargetDatabaseImpl.accept(TargetDatabaseImpl.java:56) 
    ... 37 more 

在我的數據庫中,我只看到abonne表。我嘗試沒有abonne實體(沒有Entity註釋,沒有extends Group),它仍然無法正常工作。那麼看起來問題來自InheritanceType.JOINED。當我從默認繼承策略開始時,它運行良好!但我不想在根表中使用abonne數據。

任何幫助?

+0

您確定您的「Group」實體中有「Collection 」,並且「Group」實體已經擴展了「Identity」嗎? –

+0

身份應該實際上是一個'@ MappedSuperclass'的情況,即在數據庫級別實際上沒有繼承,但是您想要在Java模型的超類中定義公共字段? HTTPS://en.wikibooks。org/wiki/Java_Persistence/Inheritance#Mapped_Sperperclass –

+0

@AbdullahKhan'Group'可以包含其他'Group'或'User'。然後,我必須有一個共同的類「身份」和一個「收集」。 @AlanHay我在'MappedSuperclass'和'Entity'之間猶豫不決。我選擇這個是因爲「集合」的通用性。事實上,也許我必須使用'MappedSuperclass',但是我放棄了集合的通用性(但它不是一個真正的問題)。我已經測試了這個沒有收集和我有同樣的問題,所以它似乎收集不是問題的一部分。我見過很多使用'Joined'策略的例子,我不明白爲什麼這個例外。 – Mohicane

回答

2

異常消息是非常明顯的

您的SQL語法錯誤;檢查 對應於你的MySQL服務器版本正確的語法使用 附近「組(ID BIGINT

你的類被稱爲‘集團’,這意味着其表的默認名稱是‘集團’的手冊。這是一個保留的SQL關鍵字,因此這個名稱需要「引用」(用引號括起來),否則它將是非法的。

某些JPA提供程序(例如DataNucleus,任何其他?)會自動爲您引用,但貌似你的解決方案不是,你的解決方案是通過@Table(name=...)!向表名添加引號,或者重命名類!,或者使用自動爲你引用的JPA提供程序

即沒有任何關於所選擇的繼承(除了「SINGLE_TABLE」繼承,它不需要創建使用保留關鍵字的表)。

+0

因爲細節,我選擇這個anwser。 – Mohicane

1

您不應該命名錶組,因爲組是保留的SQL關鍵字

重命名類或添加@Table註釋以提供不同的表名稱。

+0

它使所有症狀都敏感。我試過了。有用!現在,我感到有點蠢:p – Mohicane

+0

不要覺得愚蠢:-)我經常遇到SQL關鍵字和JPA的問題。字段或像訂單這樣的實體是常見的... –