首页 文章

插入时表的主键上的@OneToOne

提问于
浏览
0

我有两张表有单向关系的表:

CREATE TABLE `document` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`created_at` datetime NOT NULL,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`partition_key` int(11) NOT NULL DEFAULT '0',
 PRIMARY KEY (`id`,`partition_key`),
) ENGINE=InnoDB AUTO_INCREMENT=38 DEFAULT CHARSET=utf8

CREATE TABLE `document_payload` (
`document_id` int(11) unsigned NOT NULL,
`document_payload` mediumtext,
`partition_key` varchar(20) DEFAULT NULL,
PRIMARY KEY (`document_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

所以这里document_payload的document_id列指的是文档的id列 . 现在我想在我的模型类中加入这两个表,方法如下:

@Data
@Entity
@JsonSnakeCase
@JsonIgnoreProperties(ignoreUnknown = true)
public class Document {

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

@NotNull
private String partitionKey;

@OneToOne(fetch= FetchType.EAGER, cascade=CascadeType.ALL)
@JoinColumn(name = "id", referencedColumnName = "document_id")
private DocumentPayload documentPayload;

@NotNull
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
@JsonSerialize(using = CustomDateSerializer.class)
private LocalDateTime createdAt;

@PrePersist
public void onCreate() {
    createdAt = LocalDateTime.now();
}

}

@Data
@Entity
@JsonSnakeCase
@JsonIgnoreProperties(ignoreUnknown = true)
public class DocumentPayload {

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

private String documentPayload;

private String partitionKey;

}

但是在坚持不懈时,它会抛出以下错误:

java.sql.SQLException: Field 'document_id' doesn't have a default value

我尝试了使用@joincolumn但没有帮助的方式@PrimaryKeyJoinColumn,我想将自动生成的id值传播到dcoument_payload表作为document_id,我在这里缺少什么?

3 回答

  • 0

    Db故障:你只是忘了AUTO_INCREMENT声明

    CREATE TABLE `document_payload` (
    `document_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `document_payload` mediumtext,
    `partition_key` varchar(20) DEFAULT NULL,
    PRIMARY KEY (`document_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
    

    你需要它,因为你使用 IDENTITY 作为自动生成类型

  • 0
    `id`          bigint(20)       NOT NULL AUTO_INCREMENT,
    `document_id` int(11) unsigned NOT NULL,
    

    DATATYPE必须一致(不包括 NULLAUTO_INCREMENT ) .

  • 0

    Document.documentPayload 中,你应该使用另一个列名而不是 id ,因为它已经映射了 Document.id 属性,也没有必要使用referencedColumnName,因为你正在映射 DocumentPayload 实体的主键,文档声明默认情况下它提供:

    与引用表的主键列相同的名称 .

    所以 Document 课程将是:

    @Data
    @Entity
    @JsonSnakeCase
    @JsonIgnoreProperties(ignoreUnknown = true)
    public class Document {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @NotNull
    private String partitionKey;
    
    @OneToOne(fetch= FetchType.EAGER, cascade=CascadeType.ALL)
    @JoinColumn(name = "fk_document_id") // you can use whatever name you want unless it's already used for this table.  
    private DocumentPayload documentPayload;
    
    @NotNull
    @Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
    @JsonSerialize(using = CustomDateSerializer.class)
    private LocalDateTime createdAt;
    
    @PrePersist
    public void onCreate() {
        createdAt = LocalDateTime.now();
    }
    

    请注意,您不应该为自动生成的id属性实现setter,因为一旦生成它就不应该更改它,我建议添加 @Setter(AccessLevel.NONE) (在字段声明中),lombok将不会生成setter方法 .

相关问题