【问题标题】:Hibernate joined table inheritance im combination with OneToOne and @MapsIdHibernate 与 OneToOne 和 @MapsId 结合的表继承
【发布时间】:2018-08-10 17:28:25
【问题描述】:

将 Hibernate 与 mysql 结合使用。

当我尝试从联接表继承的子级创建 @OneToOne 关系时,同时还使用 @MapsId 映射联接表子级的 Id。

为了测试它,我什至创建了一个具有以下结构的测试项目:

加入表父

@Entity
@Table(name = "test_joined_bases")
@Getter
@Setter
@NoArgsConstructor
@Inheritance(strategy = InheritanceType.JOINED)
public class AJoinedBase implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
}

加入表子

@Entity
@Table(name = "test_joined_children")
@Getter
@Setter
@NoArgsConstructor
@PrimaryKeyJoinColumn(name = "id")
public class JoinedChild extends AJoinedBase {
    @OneToOne(mappedBy = "note", fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = false)
    private NoteContent content;
}

OneToOne-扩展

@Entity
@Table(name = "test_joined_child_extensions")
@Getter
@Setter
@NoArgsConstructor
public class JoinedChildExtension implements Serializable {
    @Id
    private Long id;

    @OneToOne(fetch = FetchType.LAZY)
    @MapsId
    private JoinedChild joinedChild;
}

但是,我什至无法启动 spring boot 应用程序而不会引发错误。问题似乎是 Hibernate 找不到引用实体的键列(这里:JoinedChild),因此在调用 columnIterator.next(); 时抛出 NullPointerException。我相信发生这种情况是因为由于联接表继承,密钥被保存在一个 WrappedValue 中。
谁能帮我解决这个问题,或者这是 Hibernate ORM 的问题吗?

堆栈跟踪

在构建项目时,我收到以下错误:

2018-08-10 18:54:20.611  WARN 9836 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is java.util.NoSuchElementException
[...]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is java.util.NoSuchElementException
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1706) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:579) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:501) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1089) ~[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:859) ~[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243) [spring-boot-2.0.2.RELEASE.jar:2.0.2.RELEASE]
    at com.studynote.StudynoteBackendApplication.main(StudynoteBackendApplication.java:27) [classes/:na]
Caused by: java.util.NoSuchElementException: null
    at java.util.ArrayList$Itr.next(ArrayList.java:862) ~[na:1.8.0_171]
    at org.hibernate.cfg.annotations.TableBinder.linkJoinColumnWithValueOverridingNameIfImplicit(TableBinder.java:724) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.cfg.PkDrivenByDefaultMapsIdSecondPass.doSecondPass(PkDrivenByDefaultMapsIdSecondPass.java:37) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1640) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1597) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:861) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:888) ~[hibernate-core-5.2.17.Final.jar:5.2.17.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57) ~[spring-orm-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390) ~[spring-orm-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377) ~[spring-orm-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341) ~[spring-orm-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1765) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1702) ~[spring-beans-5.0.6.RELEASE.jar:5.0.6.RELEASE]
    ... 16 common frames omitted

【问题讨论】:

  • 为什么你认为必须使用 MapsId ?
  • 因为我希望相关实体(JoinedChildExtension)自动从OneToOne(JoinedChild)的另一端获取id。
  • 能否贴出底层数据模型

标签: spring hibernate


【解决方案1】:

@MapsId 非常适合与@OneToOne 关系一起使用。请参阅这些文章了解用法:

One-to-One Relationship in JPA.

The best way to map a @OneToOne relationship with JPA and Hibernate.

但是,NoSuchElementException 在堆栈跟踪中可能是因为将@Inheritance(strategy = InheritanceType.JOINED)@MapsId 一起使用。这些 Hibernate 问题单中描述了该问题: HHH-13335HHH-13295HHH-7135

目前,所有三张票都未解决。我们必须等待这个错误被修复。同时,您可以使用InheritanceType.SINGLE_TABLEInheritanceType.TABLE_PER_CLASS@MapsId 作为解决方法。有关这些 InheritanceType 替代方案的用法,请参阅 this article

【讨论】:

    【解决方案2】:

    @MapId 是为嵌入 id 设计的 有关更多详细信息,您可以阅读here 我已经解决了我用 @JoinColumn("nameOfColumn") 替换 @MapId("nameOfColumn") 的问题

    【讨论】:

      猜你喜欢
      • 2011-03-25
      • 1970-01-01
      • 2015-03-16
      • 2011-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-02
      • 2021-10-02
      相关资源
      最近更新 更多