简体   繁体   English

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

[英]JPA 2.0 Bidirectional OneToOne doesn't create FK Column in DB

I have two very simple JPA entities that I used for learning purposes. 我有两个非常简单的JPA实体,用于学习目的。 Now, I tried to create a bidirectional one-to-one relation, but at DB level only the connection on the Employee side is created: 现在,我尝试创建双向一对一关系,但在DB级别,只创建了Employee端的连接:

ID PARKINGSPACE_ID

While on the PARKINGSPACE side this is what's created PARKINGSPACE方面,这就是创造的东西

ID

I'm sorry if this is trivial question but I really don't see what's wrong. 如果这是一个微不足道的问题,我很抱歉,但我真的没有看到什么是错的。 I tried to add the target entity on the parking space side, making both sides of the relation mandatory. 我试图在停车位一侧添加目标实体,使关系的两侧都是强制性的。 I used the relation in other cases also, without problems. 我在其他情况下也使用了这种关系,没有问题。 But I want to understand what's the problem here. 但是我想知道这里的问题是什么。

I use JPA 2.0 with hibernate 4.1.7 as provider and H2 as the underlying DB. 我使用JPA 2.0,hibernate 4.1.7作为提供程序,H2作为底层数据库。 Everything is run in the Java SE env. 一切都在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 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>

There are some errors in the console: 控制台中有一些错误:

ERROR: Table "EMPLOYEE" not found; SQL statement: alter table Employee drop constraint FK4AFD4ACE384A747F [42102-168]

You don't need two foreign keys in the database to materialize a single association. 数据库中不需要两个外键来实现单个关联。 One is sufficient. 一个就足够了。

To get the parking space of a given employee, you look for the row in the parking space table which has the ID equal to the PARKINGSPACE_ID of the given employee. 要获取给定员工的停车位,您需要在停车位表中查找ID等于给定员工的PARKINGSPACE_ID的行。

To get the employee given a parking space, you look for the row in the employee table which has the PARKINGSPACE_ID equal to the ID if the given parking space. 为了给员工一个停车位,你可以找到员工表中的行,如果给定的停车位,该行的PARKINGSPACE_ID等于ID

If there were two foreign keys, the parking space could reference an employee which would reference another parking space, leaving the database in an incoherent state. 如果有两个外键,则停车位可以引用将引用另一个停车位的员工,使数据库处于不连贯状态。

You did not get the meaning of Bidirectional in JPA. 你没有在JPA中得到双向的含义。

It does not mean that it will create foreign keys on the both tables and actually only one foreign key is sufficient to create a join. 这并不意味着它将在两个表上创建外键,实际上只有一个外键足以创建连接。 In your case 在你的情况下

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

so in this case we don't require a fk in PARKINGSPACE table. 所以在这种情况下我们不需要在PARKINGSPACE表中使用fk。 The bidirectional in JPA means we have the reference of both the entities in each one ie while fetching one entity jpa can also fetch other relational entity. JPA中的双向意味着我们在每个实体中都引用了两个实体,即在获取一个实体jpa时也可以获取其他关系实体。

In your case while fetching Employee you will automatically get Parkingspace entity and vice versa since you are using one to one relationship which is by default eager fetch. 在您获取Employee时,您将自动获取Parkingspace实体,反之亦然,因为您使用的是一对一关系,默认情况下是eager fetch。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM