我有两个非常简单的JPA实体,用于学习目的。现在,我尝试创建双向一对一关系,但在数据库级别,只创建了员工端的连接:
ID PARKINGSPACE_ID
在 PARKINGSPACE 一侧,这就是创建的内容
ID
如果这是一个微不足道的问题,我很抱歉,但我真的没有看到什么是错的。我试图在停车位一侧添加目标实体,使关系的两侧都是强制性的。我在其他情况下也使用了这种关系,没有问题。但我想了解这里的问题是什么。
我使用JPA 2.0,hibernate 4.1.7作为提供者,H2作为底层数据库。一切都在Java SE环境中运行。
@Entity
public class Employee {
@Id
@GeneratedValue
private int id;
@OneToOne
private ParkingSpace parkingSpace;
//...
}
@Entity
public class ParkingSpace {
@Id
@GeneratedValue
private int id;
@OneToOne(mappedBy = "parkingSpace")
private Employee employee;
//..
}
的persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="MenusService" transaction-type="RESOURCE_LOCAL">
<properties>
<!-- JPA specific -->
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost//d:/apps/h2/db/menus;MVCC=TRUE"/>
<!-- JPA provider specific -->
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
</properties>
</persistence-unit>
控制台中有一些错误:
ERROR: Table "EMPLOYEE" not found; SQL statement:
alter table Employee drop constraint FK4AFD4ACE384A747F [42102-168]
答案 0 :(得分:4)
数据库中不需要两个外键来实现单个关联。一个就足够了。
要获取给定员工的停车位,您需要在停车位表中查找ID
等于给定员工的PARKINGSPACE_ID
的行。
为了给员工一个停车位,如果给定的停车位,你会在员工表中查找PARKINGSPACE_ID
等于ID
的行。
如果有两个外键,停车位可以引用一个会引用另一个停车位的员工,使数据库保持不连贯状态。
答案 1 :(得分:0)
你没有在JPA中得到双向的含义。
这并不意味着它将在两个表上创建外键,实际上只有一个外键足以创建连接。 在你的情况下
SELECT e.* from EMPLOYEE e INNER JOIN PARKINGSPACE p ON e.PARKINGSPACE_ID=p.ID
SELECT p.* from PARKINGSPACE p INNER JOIN EMPLOYEE e ON p.ID=e.PARKINGSPACE_ID
所以在这种情况下我们不需要PARKINGSPACE
表中的fk。
JPA中的双向意味着我们在每个实体中都引用了两个实体,即在获取一个实体jpa时也可以获取其他关系实体。
在您获取Employee时,您将自动获取Parkingspace实体,反之亦然,因为您使用的是一对一关系,默认情况下是eager fetch。