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

Java Hibernate/JPA映射同名的复合主键和外键,java,hibernate,jpa,Java,Hibernate,Jpa,我的数据库是: 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 K

我的数据库是:

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")
对于表1中的1,我们可以在表2中有多行

我的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
@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
我的Table1Id类是:

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

    private Long fileId;

    private String geoZone;

... Others attributes and getter and setter
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
我的TABLE2实体是:

@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
@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 Table1Id implements Serializable {
    private static final long serialVersionUID = -8618317422024959144L;

    private Long fileId;

    private String geoZone;

... Others attributes and getter and setter
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])
我尝试了引用列、主键连接列和许多其他内容,但通过在internet上阅读,它可以解决数据库建模问题。 我认为问题在于主键和外键在两个表中具有相同的名称,但我可能错了。。。 我要求您确认一下,或者您是否有解决方案

提前感谢你,因为一周内我一直在寻找解决方案,但没有一个解决方案是有效的

编辑: 我将表名更改为toto,该名称在我的数据库中不存在,并且我在另一个fk id中遇到了相同的错误。hibernate似乎没有连接到我的数据库。 但若我从TABLE1中删除复合键,使其在Table2Entity和Project中的join_列中只有file_id,但这并不是我想要的。 这让我恶心,我根本不明白问题出在哪里。 这个错误告诉我们RDJ_STAT pk是唯一的文件ID,但不是,就像hibernate喝醉了一样

编辑2: 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>

错误的原因是
@ManyToOne
尝试使用
@OneToOne

    @OneToMany(fetch = FetchType.EAGER)
    ...
    private Table1Entity table1Entity;

是的,可能是两个类都使用了相同的名称。尝试将
table=“TABLE1”
放入联接列定义中:

编辑:在eclipse中放置
table=“TABLE1”
导致了一个验证错误。我猜文档会说,如果忽略它,它将指向目标实体表。但是,上面描述的类导致了此验证错误

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

我按照要求添加了
referencedColumnName

@JoinColumns({@JoinColumn(name = "FILE_ID", referencedColumnName="FILE_ID", insertable = false, updatable = false), //
        @JoinColumn(name = "GEO_ZONE", referencedColumnName="GEO_ZONE", insertable = false, updatable = false)})
因此,它在Wildfly 9.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

因此,我没有尝试插入任何行或任何内容,但似乎可以有多个
TABLE2
条目引用一个TABLE1条目,每个条目都有一个唯一的
recordNum
,用于此模式。

为什么PK列不可插入/更新?我使用这些文档来定义我的复合标识,因此使用关系字段作为@IdI的(一部分)必须在joincolumn或column或hibernate中放置insertable=false、Updateable=false eather。在这里,我没有真正的理由就把它放进了这两本书,并且我跟踪了每一本图托,stackoverflow和其他网站上的每一个帮助。我看到它仍然不起作用的唯一原因是数据库问题,但可能不是很好不,你没有遵循我链接的文档。。。他们使用关系字段作为Id,而不是像您这样重复转储。确实,没有尝试过,但我第一次看到这样的内部类。但是我试着告诉你!但这很像EmbeddedId否?一位朋友在其计算机上尝试了此代码。他添加了referencedColumnName和equals以及散列码方法,并通过一个内部类更改了我的id类。它可以在PC上工作。唯一不同的是配置,或者hibernate上有缓存吗?海报建议T1>T2是一对多,那么这怎么可能是一个修复?它会改变什么?事实上,我有很多关系我注意到你现在变成了一个女人了?我能解释一下吗?因为一个家庭必须有一份清单,对吗?或者我缺少了一些硬性内容,我有
org.hibernate.AnnotationException:找不到预期的辅助表:没有可用于com.sacre.entity.Table2Entity的表1
我将搜索您的解决方案之前是否有此功能,什么都没有。但月食什么也没说。你知道有没有像hibernate缓存之类的东西吗?因为当我读取第一个错误时,hibernate似乎没有在表1上看到我的复合键,因为
引用了主键(表1[FILE\u ID])