2017-08-30 31 views
0

我有下面两个表具有单向关系:@OneToOne上表的主键不工作时插入

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_ID document_payload的列是指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 

我试过@PrimaryKeyJoinColumn我使用@joincolumn的方式,但没有帮助,我想传播ID为dcoument_payload表的自动生成的值作为document_id,我在这里丢失了什么?

+0

你如何坚持你的实体? –

+0

使用EntityManager的持久方法。 this.getEntityManager.persist(document) – user2098324

+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为自动生成类型

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

数据类型必须是一致的(不含NULLAUTO_INCREMENT)。

0

Document.documentPayload你应该使用其他列名比id,因为它已经被映射为Document.id财产,也这是没有必要使用referencedColumnName为你映射DocumentPayload实体的主键,文档指出默认情况下它呈现:

The same name as the primary key column of the referenced table.

所以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(); 
} 

只是要注意,你不应该实施本身tter为自动生成的id属性,因为一旦生成它就不应该改变,并且我建议添加@Setter(AccessLevel.NONE)(在字段声明中),并且lombok不会生成setter方法。