【问题标题】:Hibernate: @OneToOne not producing "one to one" relationship in database休眠:@OneToOne 不在数据库中产生“一对一”关系
【发布时间】:2016-04-25 18:52:00
【问题描述】:

我对 JPA 和 Hibernate 比较陌生,我想看看 @OneTo One 注释是如何工作的,假设我有一个具有以下关系的实体“任务”:

 @OneToOne
    @JoinColumn(name = "manager_id")
    private Manager manager;

还有实体“经理”:

@Entity
@Table(name = "manager")
public class Manager {

 @Id
 @GeneratedValue(strategy=GenerationType.IDENTITY)
 private Long id;
 private String name;

 public Manager() {
 }

当我运行测试文件并将“hibernate.hbm2ddl.auto”设置为“更新”时,我在数据库中得到了一个多对一关系(如您所见,没有任何类型的唯一约束' d 使其成为一对一的关系):

CREATE TABLE IF NOT EXISTS `timesheet`.`task` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
  `completed` BIT(1) NOT NULL,
  `description` VARCHAR(255) NULL DEFAULT NULL,
  `manager_id` BIGINT(20) NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  INDEX `FK3635851B178516` (`manager_id` ASC),
  CONSTRAINT `FK3635851B178516`
    FOREIGN KEY (`manager_id`)
    REFERENCES `timesheet`.`manager` (`id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

为了确保这一点,我尝试添加具有相同经理 ID 的两条记录并且确实添加了,我还尝试设置唯一约束,例如“@Table(name = "Task",uniqueConstraints = @UniqueConstraint(columnNames =...”,但没有成功。 那么为什么会发生这种情况?如果没有应用程序逻辑来验证,使用 @OneToOne 注释的优点是什么?

另外,Hibernate 是否有可能无法正确生成 DDL? (我知道通过休眠生成模式仅用于测试)

【问题讨论】:

  • 提供你的第二个实体类
  • 你的意思是什么实体?任务和管理器都在那里
  • 我还期望@OneToOne 关系生成一个唯一约束。我看不出接受的答案...如何回答这个问题!
  • 我从未停止过面对这个问题,我真正的解决方案是使用现有的模式并在那里定义一对一关系,我接受了答案,因为当我问这个问题时,我刚刚加入 StackOverflow 并认为我需要接受一个答案。

标签: java sql hibernate jpa


【解决方案1】:

在单向关系中,如果您将其标记为“optional=false”,您将获得预期的唯一约束。当然,如果您将连接列明确设置为唯一,您也会得到它。

所以要么

@OneToOne(optional=false)
    @JoinColumn(name = "manager_id")
    private Manager manager;

@OneToOne
    @JoinColumn(name = "manager_id", unique=true)
    private Manager manager;

那么为什么需要将其标记为非可选? 我的猜测是,当一个值是可选的时,该列可以包含许多空值,但是在许多数据库中,当存在唯一约束时,这是无法做到的。不过,您可以在 MySQL 中执行此操作,因此在这种情况下,Hibernate 生成器可能没有考虑数据库(一个错误?)。 请参阅有关 MySQL 处理 null 的讨论here

【讨论】:

    【解决方案2】:

    我也遇到了这个问题,我只需要添加引用的列,这样我就可以得到一个生成的表:

    @Entity(name = "news")
     public class News extends BaseEntity {
    
        @Column(length = 500)
        private String title;
        @Column(length = 2000)
        private String description;
    
        @OneToOne(optional = false, fetch = FetchType.LAZY, cascade = CascadeType.ALL)
        @JoinColumn(name = "file_id", referencedColumnName = "id", unique = true)
        private Picture picture;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多