2016-11-25 200 views
0

我有問題與Hibernate實現InheritanceType.JOINED策略。InheritanceType.JOINED策略與Spring Boot不起作用

我有這種異常的所有時間:

Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory 
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:954) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:882) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final] 
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353) ~[spring-orm-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373) ~[spring-orm-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362) ~[spring-orm-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1642) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579) ~[spring-beans-4.3.3.RELEASE.jar:4.3.3.RELEASE] 
    ... 16 common frames omitted 
Caused by: org.hibernate.MappingException: Could not instantiate persister org.hibernate.persister.entity.JoinedSubclassEntityPersister 
    at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:112) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:77) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:348) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final] 
    ... 22 common frames omitted 
Caused by: org.hibernate.AssertionFailure: Table school_service.abstract_person not found 
    at org.hibernate.persister.entity.AbstractEntityPersister.getTableId(AbstractEntityPersister.java:5118) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.persister.entity.JoinedSubclassEntityPersister.<init>(JoinedSubclassEntityPersister.java:433) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_51] 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_51] 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_51] 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422) ~[na:1.8.0_51] 
    at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:96) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    ... 26 common frames omitted 

我創建了一個春天啓動/搖籃項目複製這裏的錯誤:https://github.com/tamershahin/JoinTableTest

這是主類:

@Entity 
@Inheritance(strategy = InheritanceType.JOINED) 
@DiscriminatorColumn(name = "person_type") 
@Table(name = "abstract_person",schema = "school_service") 
@AllArgsConstructor 
@NoArgsConstructor 
public class Person { 

    @Id 
    @GeneratedValue() 
    @Column(name="person_id") 
    private Long id; 

    @Column(nullable = false, length = 125, name="name") 
    @Getter 
    @Setter 
    String name; 

    @Column(name = "person_type", nullable = false) 
    @[email protected] 
    String personType; 

} 

和這個擴展它的人:

@Entity 
@DiscriminatorValue("student") 
@Table(name = "student_detail",schema = "school_service") 
@PrimaryKeyJoinColumn(name = "student_id", referencedColumnName = "person_id") 
@Builder(toBuilder = true) 
@NoArgsConstructor 
@AllArgsConstructor 
public class Student extends Person { 

    @Column(length = 32, nullable = false) 
    @Getter 
    @Setter 
    String email; 

    @Column(length = 32, nullable = false) 
    @Getter 
    @Setter 
    String className; 
} 

本質上,我遵循JPA指導原則,事實上,如果切換到InheritanceType.TABLE_PER_CLASS策略一切正常,但該實現不是我所需要的。

我調試了一下類:... /休眠核心 - 5.0.11.Final-sources.jar /org/hibernate/persister/entity/AbstractEntityPersister.java

,我注意到,這代碼位:

for (int j = 0; j < tables.length; j++) { 
      if (tableName.equalsIgnoreCase(tables[j])) { 
       return j; 
      } 
     } 

永遠不會返回正確的表,因爲tableName始終包含模式,表不會。因此它無法找到表。

難道是我錯誤配置/濫用某些東西,或者這是一個適當的錯誤嗎?

謝謝大家。

牛逼

編輯:

我使用這個屬性:

spring.jpa.hibernate.ddl-AUTO =創造降

所以DB應由Hibernate根據他的需要生成,但是在它之前一切都崩潰了。

我也試圖手動創建類,如下解釋: http://www.javaroots.com/2013/07/hibernate-inheritance-joined-strategy.html

,但沒有成功。

UPDATE: 後@crafarlo評論我開始玩application.properties,我發現,移除這個配置:

spring.jpa.properties.hibernate.default_schema

會做的伎倆。

這是我的全部配置:

urlwithoutschema=jdbc:mysql://localhost:3306/ 
spring.datasource.url=${urlwithoutschema}${spring.datasource.schema} 
spring.datasource.username=school 
spring.datasource.password=school 
spring.datasource.schema=school_service 
spring.datasource.driver-class-name=com.mysql.jdbc.Driver 
spring.jpa.hibernate.ddl-auto=none 
spring.jpa.show-sql=true 
#spring.jpa.properties.hibernate.default_schema=${spring.datasource.schema} 

我不明白爲什麼這會影響映射類表,但它確實..任何線索?

+0

什麼都有「@Inheritance(策略= InheritanceType.TABLE_PER_CLASS)」增加了鑑別列得做JOINED? –

+0

對不起,我的錯:你說得對,我在這裏複製粘貼的代碼是來自另一個使用TABLE_PER_CLASS的測試項目。 但在github上共享的代碼是正確的。 而且我確認JOINED不起作用。 – Tamer

+0

@Tamer檢查我的回覆,你忘記了抽象類中的鑑別器列。 Hibernate不是那麼聰明,只能單獨做:) – cralfaro

回答

0

表school_service.abstract_person沒有找到

表school_service.abstract_person丟失。對於TABLE_PER_CLASS,這不是必需的,但對於JOINED,您需要一個表用於層次結構中的每個實體。

+0

我現在要求hibernate創建表,這是奇怪的一點。創建它們的時間並且只發生在InheritanceType.JOINED – Tamer

0

你沒有通過JOIN做繼承。你應該使用這個:

@Entity 
@Inheritance(strategy = InheritanceType.JOINED 
@DiscriminatorColumn(name = "person_type") 
@Table(name = "abstract_person",schema = "school_service") 
@AllArgsConstructor 
@NoArgsConstructor 
public abstract class Person { 
    @Id 
    @Getter 
    @Setter 
    @Column(name = "ID") 
    @GeneratedValue(...) 
    private Integer id; 
    //... 



@Entity 
@DiscriminatorValue("student") 
@Table(name = "student_detail",schema = "school_service") 
@Builder(toBuilder = true) 
@NoArgsConstructor 
@AllArgsConstructor 
public class Student extends Person { 

    @Column(length = 32, nullable = false) 
    @Getter 
    @Setter 
    String email; 

    @Column(length = 32, nullable = false) 
    @Getter 
    @Setter 
    String className; 
} 

而在你的子類表中定義的PK這是一樣的,在主表。然後加入將工作

UPDATE:

你也忘了在抽象類

@DiscriminatorColumn(name = "person_type", discriminatorType = DiscriminatorType.STRING) 

... 

@Getter @Setter 
@Column(name = "person_type", nullable = false, insertable = false, updatable = false) 
@Enumerated(value = EnumType.STRING) 
private String type; 
+0

對不起,我的錯:你說得對,我在這裏複製粘貼的代碼來自一個使用TABLE_PER_CLASS的測試項目。 但在github上共享的代碼是正確的。 而且我確認JOINED不起作用。 – Tamer

+0

我試過你的代碼,指定了列並設置了@Enumerated註解。我還宣佈Enum擁有學生和教師的價值觀。仍然沒有工作..是git代碼爲你工作? – Tamer

+0

@Tamer我沒有嘗試它,不在內存中,我現在不想重新創建我的模式:),我有完全相同的情況工作告訴我你的電子郵件,我會與你分享 – cralfaro

相關問題