我在下面有两个具有单向关系的表:
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,我在这里缺少什么?
答案 0 :(得分: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
作为自动生成类型
答案 1 :(得分:0)
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`document_id` int(11) unsigned NOT NULL,
DATATYPE必须一致(不包括NULL
和AUTO_INCREMENT
)。
答案 2 :(得分:0)
在Document.documentPayload
中,您应该使用另一个列名而不是id
,因为它已经为Document.id
属性进行了映射,也没有必要使用DocumentPayload
3}}当你正在映射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();
}
类将是:
@Setter(AccessLevel.NONE)
请注意,您不应该为自动生成的id属性实现setter,因为它生成后不应该更改,我建议添加@Assert\Type(type="integer", groups={"group1"})
(在字段声明中),并且referencedColumnName不会生成setter方法。