JPA 2.0双向OneToOne不会在DB中创建FK列

时间:2013-11-21 09:21:20

标签: java hibernate jpa jpa-2.0

我有两个非常简单的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]

2 个答案:

答案 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。