问题
I have two classes/tables (Metafile and RowCount) with a one to one relation. Rowcount only applys to certain metafiles. Currently I have this set up (simplified):
MetaFile.java
@Entity
@Table(name = "file")
public class MetaFile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "file_id")
private int fileId;
// getters, setters, constructors...
}
RowCount.java
@Entity
@Table(name = "row_count")
public class RowCount implements Serializable {
@OneToOne
@JoinColumn(name="file_id")
private MetaFile file;
@Id
@Column(name="file_id")
private int file_id; // duplicate field needed so that crudrepo would recognise the id
private int rows;
public RowCount(MetaFile file, int rows) {
this.file = file;
this.rows = rows;
this.file_id = file.getFileId();
}
// getters, setters...
}
I'm using crudrepositories for both to simplify persistance.
I first save the metafile to get an ID assigned, then I create a rowcount object using that metafile with the new ID and save it (shown below). This second save fails however, as the metafile isn't persisted to the database immediately, and the foreign key constraint fails.
metaFile = fileRepository.save(metaFile);
rowCountRepository.save(new RowCount(metaFile,getNumberOfRows(file));
The metaFile definitely gets a valid id assigned to it. Is there a way to make sure these two persists happen in order?
Thanks!
回答1:
You can change your mapping with @mapsId
as suggested by Hadi J to have a single pk/fk column in RowCount
@Entity
@Table(name = "row_count")
public class RowCount implements Serializable {
@OneToOne
@JoinColumn(name = "file_id")
@MapsId
private MetaFile file;
@Id
@Column(name="file_id")
private int file_id;
private int rows;
public RowCount(MetaFile file, int rows) {
this.file = file;
this.rows = rows;
}
// getters, setters...
}
I would use a bidirectional relationship to simplify saving:
@Entity
@Table(name = "file")
public class MetaFile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "file_id")
private int fileId;
// getters, setters, constructors...
@OneToOne(cascade = {CascadeType.ALL}, mappedBy = "file")
private RowCount rowCount;
}
This way you can just set the relationship and save
RowCount rowCount = new RowCount(metaFile, getNumberOfRows(file));
metaFile.setRowCount(rowCount);
metaFile = fileRepository.save(metaFile);
来源:https://stackoverflow.com/questions/49921243/one-to-one-unidirectional-mapping-with-same-primary-key-in-hibernate