繁体   English   中英

使用 JPA 映射复合主键和外键

[英]Mapping composite primary and foreign keys with JPA

我有两个表:A 和 B。都有一个复合主键。 表 B 的 PK 也是表 A 主键的外键。

当我尝试获取映射表 BI 的类的实例时,出现此异常:

org.hibernate.TypeMismatchException

该应用程序是一个 Spring Boot 应用程序。 源代码可在Github 上获得

表B的代码来源为:

@Entity @Table(name="usuarios")
public class UsuarioEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    @EmbeddedId @AttributeOverrides( {
        @AttributeOverride(name="perTipoUsu", column=@Column(name="per_tipo_usu", nullable=false) ), 
        @AttributeOverride(name="perCodUsu", column=@Column(name="per_cod_usu", nullable=false) ) } )
    private UsuarioPKEntity pk = null;

   @OneToOne @PrimaryKeyJoinColumn
   private PersonaRelEnity personaRel = null;

   private String nombre;

   ....
}

表A的代码来源为:

@Entity @Table(name="persona_rel")
public class PersonaRelEnity implements Serializable {

    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private PersonaRelPKEntity id;

    private String persona;

   ....
}

这两个类都在包中:com.cairone.ejemplo01.entities

完整的日志输出是:

2016-09-21 12:28:24.505 错误 8568 --- [主要]
osboot.SpringApplication : 应用程序启动失败

java.lang.IllegalStateException: Failed to execute CommandLineRunner at org.springframework.boot.SpringApplication.callRunner(SpringApplication.ja

va:809) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] 在 org.springframework.boot.SpringApplication.callRunners(SpringApplication.j ava:790) [spring-boot-1.3.5. RELEASE.jar:1.3.5.RELEASE] 在 org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:777) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] 在 org.springframework .boot.SpringApplication.run(SpringApplication.java:308) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] 在 org.springframework.boot.SpringApplication.run(SpringApplication.java:1191) [ spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] 在 org.springframework.boot.SpringApplication.run(SpringApplication.java:1180) [spring-boot-1.3.5.RELEASE.jar:1.3。 5.RELEASE] 在 com.cairone.ejemplo01.App.main(App.java:74) [classes/:na] 引起:org.springframework.dao.InvalidDataAccessApiUsageException:
org.hibernate.TypeMismatchException:为 com.cairone.ejemplo01.entities.PersonaRelEnity 类提供了错误类型的 id。 预期:类 com.cairone.ejemplo01.entities.PersonaRelPKEntity,得到类
com.cairone.ejemplo01.entities.UsuarioPKEntity; 嵌套异常是
java.lang.IllegalArgumentException: org.hibernate.TypeMismatchException: 为类 com.cairone.ejemplo01.entities.PersonaRelEnity 提供了错误类型的 id。 预期:类 com.cairone.ejemplo01.entities.PersonaRelPKEntity,在 org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExce ptionIfPossible(Entity3ManagerFactory-Utils)~spring[:
4.2.6.RELEASE.jar:4.2.6.RELEASE] 在 org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionI fPossible(HibernateJpaDialect.java:227) ~[spring-orm-
4.2.6.RELEASE.jar:4.2.6.RELEASE] 在 org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExce ptionIfPossible(AbstractEntityManagerFactoryBean.java:436) ~[spring-
orm-4.2.6.RELEASE.jar:4.2.6.RELEASE] 在 org.springframework.dao.support.ChainedPersistenceExceptionTranslator.tran slateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59) ~ [spring-tx-4.2.6.RELEASE.jar: 4.2.6.RELEASE] 在 org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataA ccessUtils.java:213) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 在 org.springframework .dao.support.PersistenceExceptionTranslationInterceptor .invoke(PersistenceExceptionTranslationInterceptor.java:147) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(Refle cvocationInvocation) .java:179) ~[spring-aop-
4.2.6.RELEASE.jar:4.2.6.RELEASE] 在 org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProc essor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetad ataPostProcessor.java:131) ~[spring-data-jpa .4.RELEASE.jar:na] 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(Refle ctiveMethodInvocation.java:179) ~[spring-aop-
4.2.6.RELEASE.jar:4.2.6.RELEASE] 在 org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(Exp oseInvocationInterceptor.java:92) ~[spring-aop-
4.2.6.RELEASE.jar:4.2.6.RELEASE] 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(Refle ctiveMethodInvocation.java:179) ~[spring-aop-
4.2.6.RELEASE.jar:4.2.6.RELEASE] 在 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopP roxy.java:208) ~[spring-aop-4.2.6.RELEASE.jar:4.2. 6.RELEASE] at com.sun.proxy.$Proxy69.findAll(Unknown Source) ~[na:na] at com.cairone.ejemplo01.datasources.UsuarioDataSource.buscar(UsuarioDataSour ce.java:15) ~[classes/: na] 在 com.cairone.ejemplo01.App.run(App.java:33) [classes/:na] 在 org.springframework.boot.SpringApplication.callRunner(SpringApplication.ja va:806) [spring-boot-1.3. 5.RELEASE.jar:1.3.5.RELEASE] ... 6 个常见框架被省略 导致:java.lang.IllegalArgumentException:org.hibernate.TypeMismatchException:为类 com.cairone.ejemplo01.entities 提供了错误类型的 id。人物关系。 预期:类 com.cairone.ejemplo01.entities.PersonaRelPKEntity,在 org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:455) ~[hibernate-entitymanager 得到类 com.cairone.ejemplo01.entities.UsuarioPKEntity .11.Final.jar:4.3.11.Final] 在 org.hibernate.jpa.criteria.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:67) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3. 11.Final] 在 org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:323) ~[spring-data-jpa-1.9.4.RELEASE.jar:na] 在 org.springframework。 data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:68) ~[spring-data-jpa-1.9.4.RELEASE.jar:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[ na:1.8.0_74] 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_74] 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1. 8.0_74] 在 java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_74] 在 org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java) :483) ~[spring-data-commons-1.11.4.RELEASE.jar:na] 在 org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:468) ~[spring- data-commons-1.11.4.RELEASE.jar:na] 在 org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:440) ~[spring-data-commons-1.11.4 .RELEASE.jar:na] 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.6.RELEASE.jar:4.2.6.RELEASE] 在 org.springframework .data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61) ~[spring-data-commons-1.11.4.RELEASE.jar: na] 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.6.RELEASE.jar:4.2.6.RELEASE] 在 org.springframework.transaction.interceptor。 TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 在 org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] 在 org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.2.6.RELEASE] .jar:4.2.6.RELEASE] 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.6.RELEASE.jar:4.2.6.RELEASE] 在 org .springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.2.6.RELEASE.jar:4.2.6.RELEASE] .. . 16 个常见框架被省略 引起:org.hibernate.TypeMismatchException:为类 com.cairone.ejemplo01.entities.PersonaRelEnity 提供了错误类型的 id。 预期:类 com.cairone.ejemplo01.entities.PersonaRelPKEntity,在 org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:134) ~[hibernate-core-4.33 .11.Final.jar:4.3.11.Final] 在 org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1106) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]在 org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:1025) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 在 org.hibernate.type.EntityType.resolveIdentifier(EntityType. java:716) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 在 org.hibernate.type.EntityType.resolve(EntityType.java:502) ~[hibernate-core-4.3.11 .Final.jar:4.3.11.Final] 在 org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:170) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]在 org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:144) ~[hibernate-core-4.3.11.Final.jar:4.3 .11.Final] 在 org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1115) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 在 org.hibernate.loader.Loader .processResultSet(Loader.java:973) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 在 org.hibernate.loader.Loader.doQuery(Loader.java:921) ~[hibernate- core-4.3.11.Final.jar:4.3.11.Final] 在 org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:355) ~[hibernate-core-4.3.11.Final.jar:4.3.11 .Final] 在 org.hibernate.loader.Loader.doList(Loader.java:2554) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 在 org.hibernate.loader.Loader.doList (Loader.java:2540) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 在 org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2370) ~[hibernate-core- 4.3.11.Final.jar:4.3.11.Final] 在 org.hibernate.loader.Loader.list(Loader.java:2365) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final ] 在 org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:497) ~[hibernate- core-4.3.11.Final.jar:4.3.11.Final] 在 org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:387) ~[hibernate-core-4.3.11.Final.jar :4.3.11.Final] 在 org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:236) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 在 org .hibernate.internal.SessionImpl.list(SessionImpl.java:1300) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 在 org.hibernate.internal.QueryImpl.list(QueryImpl.java: 103) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final] 在 org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:573) ~[hibernate-entitymanager-4.3.11 .Final.jar:4.3.11.Final] 在 org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:449) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final] ...省略了 34 个常用帧

2016-09-21 12:28:24.508 INFO 8568 --- [主要] utoConfigurationReportLoggingInitializer :

启动 ApplicationContext 时出错。 要显示自动配置报告,请启用调试日志记录(以 --debug 开头)

 2016-09-21 12:28:24.509 INFO 8568 --- [ main] scaAnnotationConfigApplicationContext : Closing

org.springframework.context.annotation.AnnotationConfigApplicationContext@ 24b1d79b:启动日期 [Wed Sep 21 12:28:21 ART 2016]; 上下文层次结构的根 2016-09-21 12:28:24.511 INFO 8568 --- [ main] osjeaAnnotationMBeanExporter :在关闭时取消注册 JMX 暴露的 bean 2016-09-21 12:28:24.513 INFO --- [main] jm 8568 .LocalContainerEntityManagerFactoryBean : 关闭 JPA
EntityManagerFactory 用于持久性单元“默认”

这是相关部分:

org.hibernate.TypeMismatchException:为 com.cairone.ejemplo01.entities.PersonaRelEnity 类提供了错误类型的 id。 预期:类 com.cairone.ejemplo01.entities.PersonaRelPKEntity,得到类 com.cairone.ejemplo01.entities.UsuarioPKEntity

这是一个“派生身份”,其中一个实体的主键是从另一个相关实体的主键派生的。

我还没有遇到过与这种关系完全一样的事情,但试试这个:

@Entity
@Table(name="persona_rel")
public class PersonaRelEnity implements Serializable {

    @EmbeddedId
    private PersonaRelPKEntity pk;

    ...
}

@Embeddable
public class PersonaRelPKEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    @Column(name="per_tipo")
    private Integer perTipo;

    @Column(name="per_cod")
    private Integer perCod;

    ...
}

@Entity
@Table(name="usuarios")
public class UsuarioEntity implements Serializable {

    @EmbeddedId
    private UsuarioEntityPK id;

    @OneToOne
    @MapsId("personaRelPKEntity")
    @JoinColumns({
        @JoinColumn(name="per_tipo_usu", referencedColumnName="per_tipo"),
        @JoinColumn(name="per_cod_usu", referencedColumnName="per_cod")
    })
    private PersonaRelEnity personaRelEntity = null;

    ...
}

@Embeddable
public class UsuarioEntityPK implements Serializable {

    // matches the PK type of PersonaRelEnity
    private PersonaRelPKEntity personaRelPKEntity;

    ...
}

派生身份在 JPA 2.1 规范的第 2.4.1 节中讨论。

旁注:类名PersonaRelEnity有一个拼写错误(即Entity缺少它的第一个t )。 :-)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM