I have 2 entities with the following mapping
FileContent.java
@Entity
@Table(name="FILE_CONTENT", schema="COMMON")
public class FileContent implements Serializable{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ID")
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "FILE_ID")
private File docFile;
}
and File.java
@Entity
@Table(name="FILE", schema="COMMON")
public class File implements Serializable{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ID")
private Long id;
@Column(name = "FILE_NAME")
private String fileName;
}
So far this mapping is working fine as I can get File using fileContent.getDocFile().
So is it possible that I can map the FileContent within the File also? I tried to add the mapping in this way but it's not working, I always getting null when I access using file.getFileContent();
@Entity
@Table(name="FILE", schema="COMMON")
public class File implements Serializable{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ID")
private Long id;
@Column(name = "FILE_NAME")
private String fileName;
@OneToOne(mappedBy = "docFile", cascade = CascadeType.ALL)
private FileContent fileContent;
}
I also tried with @MapsId and @PrimaryKeyJoinColumn as suggested in here but still not able to get it to work.
What am I doing wrong?
===================================================================
Edited on 8/8/2019
Thanks for Razib for the answer, and it's working perfectly.
However I found that it's working when I select the FILE
record form the DB, but not from a freshly saved FILE
object.
File file = new File();
file.setFileName("sample.txt")
fileRepo.saveAndFlush(file);
File fileContent = new FileContent();
fileContent.set....;
fileContent.setFile(file);
fileContentRepo.saveAndFlush(fileContent);
return file;
I'm not using the Cascade
to save these entities. When I access the return file
using file.getFileContent();
and it's null.
What you are looking for is bidirectional one to one mapping. Now the mapping is done only one way. In bidirectional mapping, you need to put File
reference in FileContent
and vice versa. Check the following code snippet -
File:
@Entity
@Table(name="FILE", schema="COMMON")
public class File {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ID")
private Long id;
@Column(name = "FILE_NAME")
private String fileName;
@OneToOne(mappedBy = "file", cascade = CascadeType.ALL,
fetch = FetchType.LAZY, optional = false)
private FileContent details;
//constructors getters and setters
}
FileContent:
@Entity
@Table(name="FILE_CONTENT", schema="COMMON")
public class FileContent{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="ID")
private Long id;
@Column(name = "FILE_NAME")
private String fileName;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "FILE_ID")
private File file;
//constructors getters and setters
}
Notes:
FILE_CONTENT
with a column named FILE_ID
. FILE_ID
is the foreign key referencing the primary key of FILE.ID
.
Here in the association, the File
entity is the parent, while the FileContent
is the child. Because the foreign key is located in the FILE_CONTENT
table.
Now from your code, you can access both entities from any side like - file.getFileContent()
or fileContent.getFile()