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])