Search code examples
jpaeclipselinkrelationship

JPA optional relationship


I'm using EclipseLink.

I have an entity DIDRequest that has a one to Many relationship with DIDAllocation.

The DIDRequest does not always have an associated DIDAllocation (i.e. the DIDAlloction should be optional).

I have the following entity

@Entity
@Table(name = "tblDIDRequest")
public class DIDRequest 
{
    int id;
    @ManyToOne(optional = true)
    private DIDAllocation didAllocation;
}

The optional argument doesn't seem to be working as EclipseLink is generating a foriegn key constraint as follows:

CREATE TABLE `tblDIDRequest` (
  `ID` bigint(20) NOT NULL AUTO_INCREMENT,
  `DIDALLOCATION_ID` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`ID`),
  KEY `FK_tblDIDRequest_DIDALLOCATION_ID` (`DIDALLOCATION_ID`),
  CONSTRAINT `FK_tblDIDRequest_DIDALLOCATION_ID` FOREIGN KEY (`DIDALLOCATION_ID`) REFERENCES `tblDIDAllocation` (`ID`),

);

How do I modify the annotation so it doesn't generate the foreign key constraint?

Is there a way to have the constraint so if didAllocation exist then there must be a related entity but if it is null we don't care?


Solution

  • This works just like it should!

    A required association can be mapped by having a NOT NULL constraint on a column (to make sure it has a value) and also a FOREIGN KEY constraint, to make sure that value corresponds to the ID in another table.

    If you have an optional association, you still want a FOREIGN KEY constraint, so you can't just put gibberish into the column. But you don't have the NOT NULL constraint, so NULL indicates "the association is not present".

    `DIDALLOCATION_ID` bigint(20) DEFAULT NULL,
    

    This is nullable and has a default value of NULL.

    You may also want to set fetch = FetchType.LAZY on the association and explicitly join/eager-fetch it only when you need it - for efficiency. And in general I highly recommend all articles by Vlad Mihalcea to learn more about efficient JPA use: https://vladmihalcea.com/manytoone-jpa-hibernate/