【问题标题】:Hibernate not set foreign key休眠未设置外键
【发布时间】:2021-06-15 13:47:44
【问题描述】:

我有这个模型

public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

@OneToOne
@PrimaryKeyJoinColumn
private Address registred_address_id;

@OneToOne
@PrimaryKeyJoinColumn
private Address actual_address_id;
...

我有这个方法

private Customer addCustomer(String first_name, String last_name, String middle_name, String sex, Address address) {
    Customer customer = new Customer(first_name, last_name, middle_name, sex);
    customer.setActual_address_id(address);
    customer.setRegistered_address_id(address);
    customerRepo.save(customer);
    return customer;
}

但是hibernate没有设置actual_address_id和registered_address_id (it,s OneToOne)

休眠: 插入 进入 顾客 (名,姓,中间名,性别) 价值观 (?, ?, ?, ?) 2021-03-18 14:01:58.340 WARN 12836 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper:SQL 错误:0,SQLState:23502 2021-03-18 14:01:58.340错误12836 Подробности: Ошибочная строка содержит (6, null, null, null, null, null, male)。

【问题讨论】:

  • 请翻译错误信息
  • 错误:关系“customer”的“registred_address_id”列中的NULL违反了NOT NULL约束详细信息:错误行包含(6,null,null,null,null,null,male)。
  • @SeventhDonkey 当您使用@PrimaryKeyJoinColumn 时,这意味着id 将来自Address 实体。这可能不是你想要的。请参阅文档的this section
  • @SternK 为什么?客户必须有来自表地址的地址。
  • @SeventhDonkey 我看到您在 Customer.id 上使用 @GeneratedValue(strategy = GenerationType.IDENTITY),所以从这一点来看,您似乎想要生成 Customer.id,但是当您使用 @PrimaryKeyJoinColumn 时,应该设置 Customer.id通过 Address.id,请参阅文档中的示例(来自上面的链接)

标签: java spring hibernate


【解决方案1】:

你的映射是矛盾的。

从一方面你希望Customer.id 在插入后由数据库生成。这就是GenerationType.IDENTITYactually mean

另一方面,您尝试使用@PrimaryKeyJoinColumn,这意味着Customer.id 应该由Address.id 设置。 @PrimaryKeyJoinColumn 的正确映射应如下所示:

@Entity
public class Customer {

  @Id
  private long id;

  @OneToOne
  @PrimaryKeyJoinColumn
  private Address address;
 
  public void setAddress(Address address) {
     this.address = address;
     this.id = address.getId();
  }
  // ... 
}

但这不符合您的要求。

所以,我建议您像这样更正您的客户表:

create table customer
(
   id bigserial not null,
   reg_address_id bigint,
   act_address_id bigint,
   -- ...
   primary key(id),
   foreign key(reg_address_id) references address(id),
   foreign key(act_address_id) references address(id)
);

然后使用以下映射:

@Entity
public class Customer {

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

  @OneToOne
  @JoinColumn(name = "reg_address_id")
  private Address registredAddress;

  @OneToOne
  @JoinColumn(name = "act_address_id")
  private Address actualAddress;

  // ... 
}

【讨论】:

    猜你喜欢
    • 2012-02-05
    • 2013-03-06
    • 1970-01-01
    • 2013-02-09
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    • 2017-03-18
    • 1970-01-01
    相关资源
    最近更新 更多