Is it possible to map OneToOne relationship using an ordinary unique field as the foreign key?

Idea is simple. A Person can has a maximum one photo in the Photo table. The tables are joined by idcard field which is unique.


How to map it to achieve orphanRemoval funtionality?

There are plenty of tutorials, articles and books about mappings. Please consider working through these resources first before asking questions. Chances are, you are going to have a lot more questions which you can easily answer after getting into the topic.

Anyway, here is the solution.

@OneToOne(orphanRemoval = true)
@JoinColumn(name = "idcard", referencedColumnName = "idcard")
Photo photo;

Thank you for your kind answer for my trivial. Now I see I didn’t explain it clear enough.
I know that I can do mapping that way but:

  • make long story short: how to do it so that the service class is still able to create a Person object with the idcard value explicitly specified? Person can have idcard value without existing Photo.

  • full boring context: I would like to keep the idcard field in the Person entity. Lets say the Photo entity is the new one. And there is a plenty of code that uses Person entity wihout mapping to Photo, and uses the idcard field directly, for number of different purposes. For example the service class should be able to create Person object with explicitly given idcard value without creating corresponding Photo.

I’m just wondering if it is even possible to do mapping without changind existing list of field of the Person entity

You can create a proxy value by using entityManager.getReference(Photo.class, "some-value") which does not have to exists. You can set that value, but beware that you can’t have a foreign key constraint in such a case. You also shouldn’t call any methods on that proxy object except for the getter for the id attribute. Unless you know the value exists, calling other methods would result in an exception as that would trigger lazy initialization.

You could also map the idcard column multiple times like this:

@Column(name = "idcard")
String idcard;
@NotFound(action = IGNORE)
@OneToOne(orphanRemoval = true)
@JoinColumn(name = "idcard", referencedColumnName = "idcard", insertable = false, updatable = false)
Photo photo;

The idcard attribute is the source for writing of the idcard column. The photo association is only usable for read access. The @NotFound(action = IGNORE) annotation causes null to be initialized when the target is not found.