java - 如何在 JPA 中映射没有外键的一对一关系?

标签 java jpa jpa-2.0 hibernate-mapping one-to-one

我有 2 个具有以下映射的实体

FileContent.java

@Entity
@Table(name="FILE_CONTENT", schema="COMMON")
public class FileContent implements Serializable{

  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  @Column(name="ID")
  private Long id;

  @OneToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "FILE_ID")
  private File docFile; 

}    

File.java

@Entity
@Table(name="FILE", schema="COMMON")
public class File implements Serializable{

  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  @Column(name="ID")
  private Long id;

  @Column(name = "FILE_NAME")
  private String fileName;  

}   

到目前为止,这个映射工作正常,因为我可以使用 fileContent.getDocFile() 获取 File

那么我是否也可以将 FileContent 映射到 File 中? 我尝试以这种方式添加映射,但它不起作用,当我使用 file.getFileContent(); 访问时,我总是得到空值;

@Entity
@Table(name="FILE", schema="COMMON")
public class File implements Serializable{

  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  @Column(name="ID")
  private Long id;

  @Column(name = "FILE_NAME")
  private String fileName;  

  @OneToOne(mappedBy = "docFile", cascade = CascadeType.ALL)
  private FileContent fileContent;

}  

我还按照 here 中的建议尝试使用 @MapsId 和 @PrimaryKeyJoinColumn但仍然无法让它工作。

我做错了什么?

============================================= ====================

编辑于 2019 年 8 月 8 日

感谢 Razib 的回答,它运行良好。 但是,当我从数据库中选择 FILE 记录时,我发现它正在工作,而不是从新保存的 FILE 对象中选择。

File file = new File();
file.setFileName("sample.txt")
fileRepo.saveAndFlush(file);

File fileContent = new FileContent();
fileContent.set....;
fileContent.setFile(file);
fileContentRepo.saveAndFlush(fileContent);

return file;

我没有使用 Cascade 来保存这些实体。当我使用 file.getFileContent(); 访问返回的 file 时,它是 null

最佳答案

您正在寻找的是双向一对一映射。现在映射仅以一种方式完成。在双向映射中,您需要将File 引用放在FileContent 中,反之亦然。检查以下代码片段 -

文件:

@Entity
@Table(name="FILE", schema="COMMON")
public class File {

        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        @Column(name="ID")
        private Long id;

        @Column(name = "FILE_NAME")
        private String fileName;

        @OneToOne(mappedBy = "file", cascade = CascadeType.ALL,
           fetch = FetchType.LAZY, optional = false)
        private FileContent details;  

        //constructors getters and setters

    } 

文件内容:

@Entity
@Table(name="FILE_CONTENT", schema="COMMON")
public class FileContent{

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="ID")
    private Long id;

    @Column(name = "FILE_NAME")
    private String fileName;  

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "FILE_ID")
    private File file;   

    //constructors getters and setters
}

注意事项:

  • 上面的代码片段将创建名为 FILE_CONTENT 的表,其中包含一个名为 FILE_ID 的列。
  • FILE_ID 是引用FILE.ID 主键的外键。

  • 在关联中,File 实体是父实体,而 FileContent 实体是子实体。因为外键位于 FILE_CONTENT 表中。

  • 现在从您的代码中,您可以从任何方面访问这两个实体,例如 - file.getFileContent()fileContent.getFile()

关于java - 如何在 JPA 中映射没有外键的一对一关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57390724/

相关文章:

java - 线程 :Wait() and notify()

java - 保存 HLS 流?

Java,Glassfish JPA : NoClassDefFoundError: javax/persistence/spi/PersistenceUnitInfo (JDK6/7 only)

java - 添加新记录时 ListView 不刷新

java - 并发收集先发生关系

postgresql - native 查询插入后如何在 JPA 中获取返回 ID

java - Hibernate 3.5.0-CR-2版本是否支持JPA2.0

java - 使用 Java Spring Boot 创建 MySQL JSON 列

java - Hibernate插入问题

java - 带 @EmbeddedId 的 JPA 复合键