当前位置: 首页 > 知识库问答 >
问题:

Hibernate/JPA映射同名的复合主键和外键

戴瑞
2023-03-14

我的数据库是:

TABLE1
"FILE_ID" NUMBER NOT NULL ENABLE, 
"GEO_ZONE" VARCHAR2(2 BYTE) NOT NULL ENABLE,
PRIMARY KEY ("FILE_ID", "GEO_ZONE")

TABLE2
"FILE_ID" NUMBER NOT NULL ENABLE, 
"GEO_ZONE" VARCHAR2(2 BYTE) NOT NULL ENABLE,
"RECORD_NUM" NUMBER, 
PRIMARY KEY ("FILE_ID", "GEO_ZONE", "RECORD_NUM"),
CONSTRAINT "FK_8ULB8IEBEU6A0VK1WTNQA3MCY" FOREIGN KEY ("FILE_ID", "GEO_ZONE")

我们可以在Table2中为Table1中的1设置多行。

我的TABLE1实体是:

@Entity
@Table(name = "TABLE1")
@IdClass(Table1Id.class)
public class Table1Entity implements Serializable {
private static final long serialVersionUID = 7825109721507305471L;

@Id
@Column(name = "FILE_ID", insertable = false, updatable = false)
private Long fileId;

@Id
@Column(name = "GEO_ZONE", insertable = false, updatable = false)
private String geoZone;

... Others attributes and getter and setter

我的Table1Id类是:

public class Table1Id implements Serializable {
    private static final long serialVersionUID = -8618317422024959144L;

    private Long fileId;

    private String geoZone;

... Others attributes and getter and setter

我的TABLE2实体是:

@Entity
@Table(name = "TABLE2")
@IdClass(Table2Id.class)
public class Table2Entity implements Serializable {

    private static final long serialVersionUID = -1344497166638156145L;

    @Id
    @Column(name = "FILE_ID", insertable = false, updatable = false)
    private Long fileId;

    @Id
    @Column(name = "GEO_ZONE", insertable = false, updatable = false)
    private String geoZone;

    @Id
    @Column(name = "RECORD_NUM")
    private Long recordNum;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumns({@JoinColumn(name = "FILE_ID", insertable = false, updatable = false), //
            @JoinColumn(name = "GEO_ZONE", insertable = false, updatable = false)})
    private Table1Entity table1Entity;


... Others attributes and getter and setter

我的Table2Id类是:

public class Table2Id implements Serializable {

    private static final long serialVersionUID = -4599660767213338871L;

    private Long fileId;

    private String geoZone;

    private Long recordNum;

... Others attributes and getter and setter

当我尝试启动我的tomcat时,我有以下错误:

org.hibernate.MappingException: Foreign key (FK_8ulb8iebeu6a0vk1wtnqa3mcy:TABLE2 [FILE_ID,GEO_ZONE])) must have same number of columns as the referenced primary key (TABLE1 [FILE_ID])

我尝试使用引用列,主键连接列和许多其他东西,但是通过在互联网上阅读它,它可以解决数据库建模问题。我认为问题是主键和外键在2个表中具有相同的名称,但我可能是错的......我要求您确认它,或者您是否有解决方案。

提前感谢您,因为我搜索了一周来寻找解决方案,但没有一个解决方案是有效的。

编辑:我将表名更改为toto,这在我的数据库中不存在,并且我的另一个fk id也有相同的错误。似乎hibernate没有连接到我的数据库。但如果我从TABLE1中删除复合键,使其在Table2Entity和Project中的join_ column中只有file_。这让我恶心,我根本不明白问题出在哪里。这个错误告诉我们RDJ_ STAT pk只是FILE_ID,而不是,就像hibernate喝醉了一样

EDIT2:ojdbc版本可能是个问题吗?没有解决方案?

编辑3:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/data/jpa
        http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa">

    <context:property-placeholder location="classpath:application.properties" />

    <context:annotation-config/>

     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
            <property name="driverClassName" value="${db.driver}" />
            <property name="url" value="${db.url}" />
            <property name="username" value="${db.username}" />
            <property name="password" value="${db.password}" />
    </bean>

    <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="showSql" value="true"/>
        <property name="generateDdl" value="true"/>
        <property name="database" value="MYSQL"/>
    </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
        <property name="persistenceXmlLocation" value="classpath:persistence.xml"></property>
        <!-- spring based scanning for entity classes>-->
    </bean>

     <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>
    <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>

    <jpa:repositories base-package="com.sacre.repository" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager"/>

</beans>

共有2个答案

闻人弘雅
2023-03-14

是的,可能是两个类都使用了相同的名称。尝试在联接列定义中添加一个<code>table=“TABLE1”:

编辑:放置table="TABLE1"给我造成了eclipse中的验证错误。我猜文档说如果它被遗漏,它将指向目标实体表。但是,上面描述的类导致了这个验证错误。

当存在多个联接列时,必须指定引用的列名

我通过添加引用的列名来解决它,因为它问:

@JoinColumns({@JoinColumn(name = "FILE_ID", referencedColumnName="FILE_ID", insertable = false, updatable = false), //
        @JoinColumn(name = "GEO_ZONE", referencedColumnName="GEO_ZONE", insertable = false, updatable = false)})

因此,它在Wildfly9.0.2.Final下运行,并创建以下SQL:

create table TABLE1 (FILE_ID bigint not null, GEO_ZONE varchar(255) not null, primary key (FILE_ID, GEO_ZONE))

create table TABLE2 (FILE_ID bigint not null, GEO_ZONE varchar(255) not null, RECORD_NUM bigint not null, primary key (FILE_ID, GEO_ZONE, RECORD_NUM))

alter table TABLE2 add constraint FK_4f6hkpolrjfbm222dd74seh6 foreign key (FILE_ID, GEO_ZONE) references TABLE1

因此,我没有尝试插入任何行或任何东西,但是看起来您可能有多个< code>TABLE2条目引用TABLE1条目,每个条目都有一个唯一的< code>recordNum。

阮健
2023-03-14

错误的问题是这个< code>@ManyToOne尝试使用< code>@OneToOne:

    @OneToMany(fetch = FetchType.EAGER)
    ...
    private Table1Entity table1Entity;
 类似资料:
  • 问题内容: 我在为某些实体设置jpa映射时遇到麻烦。我有一个如下定义的父实体。 然后,我有一个带有复合键的子实体,以及此表的主键的外键,如下所示: 我知道子实体不正确,但是我不确定如何将其设置为具有复合PK。我知道我需要设置一个PK类,但是当一个字段是父类的外键时,我不确定该怎么做。一旦设置好,父级将如何引用子级实体? 任何帮助表示赞赏。 问题答案: 这受JPA 2规范的 第2.4.1节“与派生身

  • 我有两个表:A和B,都有一个复合主键。表B的PK也是表a主键的外键。 当我试图获取映射表B的类的实例时,我得到了以下异常: org.hibernate.TypeMismatchException 这两个类都位于package:com.cairone.ejemple01.entities 完整的日志输出为: 2016-09-21 12:28:24.505错误8568--[main] O.S.Boot

  • 问题内容: 我在这里搜索,但未找到任何类似的主题,因此我发布了一个新问题。 我正在使用现有数据库上的Hibernate。我们不允许更改表的结构和数据。该应用程序正在从数据库读取数据,并根据某种逻辑迁移到另一个数据存储。 现在的问题是关于复合PK映射。例如 表A具有复合PK。 表B也有一个复合PK,此复合PK的一部分是A的PK,此处也用作FK。 我尝试了几种方法,但都无济于事。谁能告诉一个有效的Hi

  • 我在jpa/Hibernate中映射复合键时遇到了问题。父实体和子实体都具有复合主键。 在运行时保存它时会出现以下异常: 我认为这是虚假的,因为有getter和setter。如果在priceRequestLegModel上使用mappedby=“leg”,在allocationModel上使用@mapsid,也会出现同样的错误。有人能指出我在这里做错了什么吗?

  • 假设您有一个表,如下所示: 可以看到列是表的主键和外键。是的,MySQL成功生成了这个表。 问题很简单,我将如何在JPA实体中映射这一点?我是否应该有映射到列的1个id和连接列的另一个字段?欢迎提出建议。

  • 我有2个表,即user和user_session。