Repository: ebean-orm/ebean
Issue: When using @PrimaryKeyJoinColumn, FK constraint generation cannot be disabled

I have a O2O relation that maps on ID column, so @PrimaryKeyJoinColumn() should be perfect for this
```java
public class Entity1 {
        ...
	@OneToOne
	@PrimaryKeyJoinColumn()
	private Entity2 entity2 = new Entity2();
}
```
In my case, both entities may exist as their own, so I have to create & save an entity2 before entity1 exists in database, but this is prevented by a FK constraint generated by ebean.
I tried adding `@DbForeignKey(noConstraint = true)` or `@PrimaryKeyJoinColumn(foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))`, but this has no effect.

## Expected behavior
When using @PrimaryKeyJoinColumn, it should be able to disable FK constraint generation  with the `@DbForeignKey` (or `@ForeignKey`) annotation.

## Actual behavior
None of the annotations is honored, a FK constraint is always generated

## Possible fix
```diff
diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java
index 5c19323b4..45c4adace 100644
--- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java
+++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java
@@ -1732,6 +1732,9 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
 
   private void addPrimaryKeyJoin(DeployBeanPropertyAssocOne<?> prop) {
 
+    if (prop.getForeignKey() != null && prop.getForeignKey().isNoConstraint()) {
+      return;
+    }
     String baseTable = prop.getDesc().getBaseTable();
     DeployTableJoin inverse = prop.getTableJoin().createInverse(baseTable);
```
This will, at least give me control, if FK constraint should be generated or not (it does not add full support for `@DbForeignKey` (onDelete / onUpdate). Maybe it would be better to support only  `@ForeignKey` in this case which is not yet parsed from the @PrimaryKeyJoinColumn annotation yet.

@rbygrave what do you think would be the better option here?

Changed files:
src/test/java/org/tests/model/onetoone/OtoUPrime.java
src/main/java/io/ebeaninternal/server/deploy/TableJoin.java
src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocOne.java
src/main/java/io/ebeaninternal/dbmigration/model/build/ModelBuildPropertyVisitor.java
src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssoc.java
src/main/java/io/ebeaninternal/dbmigration/model/build/ModelBuildIntersectionTable.java
src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java

diff --git a/src/main/java/io/ebeaninternal/dbmigration/model/build/ModelBuildIntersectionTable.java b/src/main/java/io/ebeaninternal/dbmigration/model/build/ModelBuildIntersectionTable.java
index 9c2cf29ec..e117c3ead 100644
--- a/src/main/java/io/ebeaninternal/dbmigration/model/build/ModelBuildIntersectionTable.java
+++ b/src/main/java/io/ebeaninternal/dbmigration/model/build/ModelBuildIntersectionTable.java
@@ -49,8 +49,7 @@ class ModelBuildIntersectionTable {
 
   private void buildFkConstraints() {
 
-    PropertyForeignKey foreignKey = manyProp.getForeignKey();
-    if (foreignKey == null || !foreignKey.isNoConstraint()) {
+    if (manyProp.hasForeignKeyConstraint()) {
       ctx.fkeyBuilder(intersectionTable)
         .addForeignKey(manyProp.getBeanDescriptor(), intersectionTableJoin, true)
         .addForeignKey(manyProp.getTargetDescriptor(), tableJoin, false);
diff --git a/src/main/java/io/ebeaninternal/dbmigration/model/build/ModelBuildPropertyVisitor.java b/src/main/java/io/ebeaninternal/dbmigration/model/build/ModelBuildPropertyVisitor.java
index fa7950b45..338941122 100644
--- a/src/main/java/io/ebeaninternal/dbmigration/model/build/ModelBuildPropertyVisitor.java
+++ b/src/main/java/io/ebeaninternal/dbmigration/model/build/ModelBuildPropertyVisitor.java
@@ -170,8 +170,6 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
 
     List<MColumn> modelColumns = new ArrayList<>(columns.length);
 
-    PropertyForeignKey foreignKey = p.getForeignKey();
-
     MCompoundForeignKey compoundKey = null;
     if (columns.length > 1) {
       // compound foreign key
@@ -196,7 +194,7 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
       col.setDbMigrationInfos(p.getDbMigrationInfos());
       col.setDefaultValue(p.getDbColumnDefault());
       if (columns.length == 1) {
-        if (p.hasForeignKey() && !importedProperty.getBeanDescriptor().suppressForeignKey()) {
+        if (p.hasForeignKeyConstraint() && !importedProperty.getBeanDescriptor().suppressForeignKey()) {
           // single references column (put it on the column)
           String refTable = importedProperty.getBeanDescriptor().getBaseTable();
           if (refTable == null) {
@@ -208,6 +206,7 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
           if (p.hasForeignKeyIndex()) {
             col.setForeignKeyIndex(determineForeignKeyIndexName(col.getName()));
           }
+          PropertyForeignKey foreignKey = p.getForeignKey();
           if (foreignKey != null) {
             col.setForeignKeyModes(foreignKey.getOnDelete(), foreignKey.getOnUpdate());
           }
@@ -256,9 +255,15 @@ public class ModelBuildPropertyVisitor extends BaseTablePropertyVisitor {
       }
       TableJoin primaryKeyJoin = p.getBeanDescriptor().getPrimaryKeyJoin();
       if (primaryKeyJoin != null && !table.isPartitioned()) {
-        TableJoinColumn[] columns = primaryKeyJoin.columns();
-        col.setReferences(primaryKeyJoin.getTable() + "." + columns[0].getForeignDbColumn());
-        col.setForeignKeyName(determineForeignKeyConstraintName(col.getName()));
+        final PropertyForeignKey foreignKey = primaryKeyJoin.getForeignKey();
+        if (foreignKey == null || !foreignKey.isNoConstraint()) {
+          TableJoinColumn[] columns = primaryKeyJoin.columns();
+          col.setReferences(primaryKeyJoin.getTable() + "." + columns[0].getForeignDbColumn());
+          col.setForeignKeyName(determineForeignKeyConstraintName(col.getName()));
+          if (foreignKey != null) {
+            col.setForeignKeyModes(foreignKey.getOnDelete(), foreignKey.getOnUpdate());
+          }
+        }
       }
     } else {
       col.setDefaultValue(p.getDbColumnDefault());
diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java
index 6c2ab9114..cca2e4e7e 100644
--- a/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java
+++ b/src/main/java/io/ebeaninternal/server/deploy/BeanDescriptorManager.java
@@ -1654,8 +1654,7 @@ public class BeanDescriptorManager implements BeanDescriptorMap {
     String baseTable = prop.getDesc().getBaseTable();
     DeployTableJoin inverse = prop.getTableJoin().createInverse(baseTable);
 
-    TableJoin inverseJoin = new TableJoin(inverse);
-
+    TableJoin inverseJoin = new TableJoin(inverse, prop.getForeignKey());
     DeployBeanInfo<?> target = deployInfoMap.get(prop.getTargetType());
     target.setPrimaryKeyJoin(inverseJoin);
   }
diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssoc.java b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssoc.java
index b8915f710..a03d1e713 100644
--- a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssoc.java
+++ b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssoc.java
@@ -155,6 +155,20 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty implements STree
     return foreignKey;
   }
 
+  /**
+   * Return true if foreign key constraint is enabled on this relationship (not disabled).
+   */
+  public boolean hasForeignKeyConstraint() {
+    return foreignKey == null || !foreignKey.isNoConstraint();
+  }
+
+  /**
+   * Return true if foreign key index is enabled on this relationship (not disabled).
+   */
+  public boolean hasForeignKeyIndex() {
+    return foreignKey == null || !foreignKey.isNoIndex();
+  }
+
   /**
    * Create a ElPropertyValue for a *ToOne or *ToMany.
    */
@@ -228,7 +242,7 @@ public abstract class BeanPropertyAssoc<T> extends BeanProperty implements STree
 
   /**
    * Create a new query for the target type.
-   *
+   * <p>
    * We use target descriptor rather than target property type to support ElementCollection.
    */
   public SpiQuery<T> newQuery(SpiEbeanServer server) {
diff --git a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocOne.java b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocOne.java
index c2cc6c843..5da1a43df 100644
--- a/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocOne.java
+++ b/src/main/java/io/ebeaninternal/server/deploy/BeanPropertyAssocOne.java
@@ -45,6 +45,7 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
   private final boolean orphanRemoval;
 
   private final boolean primaryKeyExport;
+  private final boolean primaryKeyJoin;
 
   private AssocOneHelp localHelp;
 
@@ -75,6 +76,7 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
 
     super(descriptor, deploy);
     primaryKeyExport = deploy.isPrimaryKeyExport();
+    primaryKeyJoin = deploy.isPrimaryKeyJoin();
     oneToOne = deploy.isOneToOne();
     oneToOneExported = deploy.isOneToOneExported();
     orphanRemoval = deploy.isOrphanRemoval();
@@ -100,6 +102,7 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
   public BeanPropertyAssocOne(BeanPropertyAssocOne source, BeanPropertyOverride override) {
     super(source, override);
     primaryKeyExport = source.primaryKeyExport;
+    primaryKeyJoin = source.primaryKeyJoin;
     oneToOne = source.oneToOne;
     oneToOneExported = source.oneToOneExported;
     orphanRemoval = source.orphanRemoval;
@@ -357,11 +360,7 @@ public class BeanPropertyAssocOne<T> extends BeanPropertyAssoc<T> implements STr
   }
 
   public boolean hasForeignKey() {
-    return foreignKey == null || !foreignKey.isNoConstraint();
-  }
-
-  public boolean hasForeignKeyIndex() {
-    return foreignKey == null || !foreignKey.isNoIndex();
+    return foreignKey == null || primaryKeyJoin || !foreignKey.isNoConstraint();
   }
 
   /**
diff --git a/src/main/java/io/ebeaninternal/server/deploy/TableJoin.java b/src/main/java/io/ebeaninternal/server/deploy/TableJoin.java
index 03cb35d6c..5d805aa20 100644
--- a/src/main/java/io/ebeaninternal/server/deploy/TableJoin.java
+++ b/src/main/java/io/ebeaninternal/server/deploy/TableJoin.java
@@ -33,11 +33,17 @@ public final class TableJoin {
    */
   private final int queryHash;
 
+  private final PropertyForeignKey foreignKey;
+
+  public TableJoin(DeployTableJoin deploy) {
+    this(deploy, null);
+  }
+
   /**
    * Create a TableJoin.
    */
-  public TableJoin(DeployTableJoin deploy) {
-
+  public TableJoin(DeployTableJoin deploy, PropertyForeignKey foreignKey) {
+    this.foreignKey = foreignKey;
     this.table = InternString.intern(deploy.getTable());
     this.type = deploy.getType();
     this.inheritInfo = deploy.getInheritInfo();
@@ -52,6 +58,7 @@ public final class TableJoin {
   }
 
   private TableJoin(TableJoin source, String overrideColumn) {
+    this.foreignKey = null;
     this.table = source.table;
     this.type = source.type;
     this.inheritInfo = source.inheritInfo;
@@ -96,14 +103,6 @@ public final class TableJoin {
     return true;
   }
 
-
-  /**
-   * Return a hash value for adding to a query plan.
-   */
-  public int queryHash() {
-    return queryHash;
-  }
-
   @Override
   public String toString() {
     StringBuilder sb = new StringBuilder(30);
@@ -114,6 +113,13 @@ public final class TableJoin {
     return sb.toString();
   }
 
+  /**
+   * Return the foreign key options.
+   */
+  public PropertyForeignKey getForeignKey() {
+    return foreignKey;
+  }
+
   /**
    * Return the join columns.
    */
diff --git a/src/test/java/org/tests/model/onetoone/OtoUPrime.java b/src/test/java/org/tests/model/onetoone/OtoUPrime.java
index 4b2bd894b..a8da23578 100644
--- a/src/test/java/org/tests/model/onetoone/OtoUPrime.java
+++ b/src/test/java/org/tests/model/onetoone/OtoUPrime.java
@@ -1,5 +1,7 @@
 package org.tests.model.onetoone;
 
+import io.ebean.annotation.DbForeignKey;
+
 import javax.persistence.Entity;
 import javax.persistence.Id;
 import javax.persistence.OneToOne;
@@ -21,6 +23,7 @@ public class OtoUPrime {
    */
   @OneToOne
   @PrimaryKeyJoinColumn
+  @DbForeignKey(noConstraint = true)
   OtoUPrimeExtra extra;
 
   @Version
@@ -32,7 +35,7 @@ public class OtoUPrime {
 
   @Override
   public String toString() {
-    return "id:"+ pid +" name:"+name+" extra:"+extra;
+    return "id:" + pid + " name:" + name + " extra:" + extra;
   }
 
   public UUID getPid() {