【问题标题】:One To One shared primary key mapping issue in Spring JPASpring JPA中的一对一共享主键映射问题
【发布时间】:2020-03-09 16:08:28
【问题描述】:

我是 Spring JPA 的新手,正在努力保存对象

'表'

  1. 父表

书头

uid int (PK), booknum varchar

  1. 子表

书籍信息

bookid(FK)(PK),备注 varchar

BookHeader.java ...

@Entity
@Table(name="tbookheader", schema="v2")
public class BookHeader implements Serializable{

  @Id
  @SequenceGenerator(name="seq-gen",sequenceName="v2.tbookheader_uid_seq",  allocationSize = 1)
  @GeneratedValue(strategy= GenerationType.IDENTITY, generator="seq-gen")
  @Column(name = "uid")
  private int uid;

  @Column(name = "booknum")
  private String bookNum;

  @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "bookHeader")
  private BookInfo bookInfo;
}

BookInfo.java

@Entity
@Table(name="tbookinfo", schema="v2")
public class BookInfo implements Serializable{

  @Id
  @Column(name = "bookid")
  private int uid;

  @OneToOne
  @JoinColumn(name="bookid",referencedColumnName="uid")
  private BookHeader bookHeader;

  private String remark;
}

我从 json 获取对象,并使用 GSON 将 josn 转换为对象。

现在我正在尝试通过 SPRING JPA 保存它

{

    BookHeader.setBookNum("tesetbooking3");

    BookHeader.setUserDate(new Date());

    BookHeader.setUserid(1111);

    BookHeader.setCrtDate(new Date());

    BookHeader.setCrtUserId(1111);

    return bookHeaderRepository.save(BookHeader);
}

但我遇到了异常:

ERROR: insert or update on table "tbookinfo" violates foreign key constraint 
"fk_tbookinfo_bookid"
  Detail: Key (bookid)=(0) is not present in table "tbookheader".

似乎生成的主键不是从父表传递过来的。

谁能帮帮我。

TIA。

【问题讨论】:

    标签: spring-boot spring-data-jpa spring-data hibernate-mapping


    【解决方案1】:

    首先,您创建了一个@OneToOne,但您没有做任何事情来表明这是一个共享主键模型。

    书头:

    @Entity
    @Table(name="tbookheader", schema="v2")
    public class BookHeader implements Serializable{
    
      @Id
      @SequenceGenerator(name="seq-gen",sequenceName="v2.tbookheader_uid_seq",  
                               allocationSize = 1)
      @GeneratedValue(strategy= GenerationType.IDENTITY, generator="seq-gen")
      @Column(name = "uid")
      private Long uid;
    
      @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "bookHeader")
      private BookInfo bookInfo;
    }
    

    图书信息:

    @Entity
    @Table(name="tbookinfo", schema="v2")
    public class BookInfo implements Serializable{
    
      @Id //dependent on BookHeader for Id
      @OneToOne
      @JoinColumn(name="bookid",referencedColumnName="uid")
      private BookHeader bookHeader;
    }
    

    其次,对于双向关系 - 正如您在此处所做的那样 - 您必须确保在持久化之前在内存模型上正确设置关系的双方。

    BookHeader header - new BookHeader();
    BookInfo info = new BookInfo();
    header.setBookInfo(info);
    info.setBookHeader(header);//will fail without this
    bookHeaderRepository.save(header);
    

    【讨论】:

      【解决方案2】:

      id 属性从int 更改为Integer

      int 属性的默认值为0,这是一个有效的外键,但数据库中没有具有该键的对象。

      【讨论】:

      • 在这种情况下,设置一个已经持久化 bookinfo 你保存对象:BookHeader.setBookinfo(bookInfo);
      猜你喜欢
      • 2021-05-26
      • 1970-01-01
      • 2011-06-12
      • 2020-11-30
      • 1970-01-01
      • 2012-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多