19

I've bumped into this example in JPA 2.0 FR Specification, 11.1.37. OneToOne Annotation, page 403:

@OneToOne(optional=false)
@JoinColumn(name="CUSTREC_ID", unique=true, nullable=false, updatable=false)
public CustomerRecord getCustomerRecord() { return customerRecord; }

Is there any reason that I should put @OneToOne(optional=false) and at that same time put @JoinColumn(... nullable=false)?

Aren't these two declarations the same? Isn't one of them redundant?
Are both of them used in DDL schema generation?

Piotr Nowicki
  • 17,914
  • 8
  • 63
  • 82

1 Answers1

34

Formally optional=false is a runtime instruction to the JPA implementation, and nullable=false is an instruction to the DDL generator. So they are not strictly redundant.

The difference can become significant when there is entity inheritance involved. If a particular mapping exists only on a subclass, and you have single table table per-hierarchy strategy, then the OneToOne mapping may be optional=false on the particular subclass that contains the mapping. However, the actual join column cannot be made not-null, since then other sub classes that share the table can't be inserted!

In practice different versions of different providers may or may not interpret either one at either time, caveat emptor.

Affe
  • 47,174
  • 11
  • 83
  • 83
  • Do you mean this behaviour work without using EAGER such as @OneToOne(optional = false, fetch= FetchType.EAGER)? – Aerox Jun 19 '20 at 08:54
  • OneToOne relationships are eager by default in JPA2. Not sure what you're asking. What behaviour? – Affe Jun 19 '20 at 16:32
  • Ok I read the wrong part of JPA in documentation. So that's fine for it in JPA2, thanks. – Aerox Jun 24 '20 at 19:40