diff --git a/src/test/java/org/tests/model/onetoone/OtoPrime.java b/src/test/java/org/tests/model/onetoone/OtoPrime.java index d1f2ddb20..771b2de9b 100644 --- a/src/test/java/org/tests/model/onetoone/OtoPrime.java +++ b/src/test/java/org/tests/model/onetoone/OtoPrime.java @@ -17,8 +17,9 @@ public class OtoPrime { /** * Automatically set Cascade PERSIST and mapped by. + * OneToOne not optional so inner join to extra. */ - @OneToOne(optional = false, cascade = CascadeType.ALL) //, mappedBy = "prime") + @OneToOne(optional = false, cascade = CascadeType.ALL) @PrimaryKeyJoinColumn OtoPrimeExtra extra; diff --git a/src/test/java/org/tests/model/onetoone/OtoUPrime.java b/src/test/java/org/tests/model/onetoone/OtoUPrime.java new file mode 100644 index 000000000..052dbf876 --- /dev/null +++ b/src/test/java/org/tests/model/onetoone/OtoUPrime.java @@ -0,0 +1,68 @@ +package org.tests.model.onetoone; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Version; +import java.util.UUID; + +@Entity +public class OtoUPrime { + + @Id + UUID pid; + + String name; + + /** + * Effectively Ebean automatically sets Cascade PERSIST and mapped by for PrimaryKeyJoinColumn. + * This OneToOne is optional so left join to extra. + */ + @OneToOne + @PrimaryKeyJoinColumn + OtoUPrimeExtra extra; + + @Version + Long version; + + public OtoUPrime(String name) { + this.name = name; + } + + public String toString() { + return "id:"+ pid +" name:"+name+" extra:"+extra; + } + + public UUID getPid() { + return pid; + } + + public void setPid(UUID pid) { + this.pid = pid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public OtoUPrimeExtra getExtra() { + return extra; + } + + public void setExtra(OtoUPrimeExtra extra) { + this.extra = extra; + } + + public Long getVersion() { + return version; + } + + public void setVersion(Long version) { + this.version = version; + } +} diff --git a/src/test/java/org/tests/model/onetoone/OtoUPrimeExtra.java b/src/test/java/org/tests/model/onetoone/OtoUPrimeExtra.java new file mode 100644 index 000000000..7c3fae318 --- /dev/null +++ b/src/test/java/org/tests/model/onetoone/OtoUPrimeExtra.java @@ -0,0 +1,50 @@ +package org.tests.model.onetoone; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Version; +import java.util.UUID; + +@Entity +public class OtoUPrimeExtra { + + @Id + UUID eid; + + String extra; + + @Version + Long version; + + public OtoUPrimeExtra(String extra) { + this.extra = extra; + } + + public String toString() { + return "exId:"+ eid +" "+extra; + } + + public UUID getEid() { + return eid; + } + + public void setEid(UUID eid) { + this.eid = eid; + } + + public String getExtra() { + return extra; + } + + public void setExtra(String extra) { + this.extra = extra; + } + + public Long getVersion() { + return version; + } + + public void setVersion(Long version) { + this.version = version; + } +} diff --git a/src/test/java/org/tests/model/onetoone/TestOneToOnePrimaryKeyJoinOptional.java b/src/test/java/org/tests/model/onetoone/TestOneToOnePrimaryKeyJoinOptional.java new file mode 100644 index 000000000..64835b68b --- /dev/null +++ b/src/test/java/org/tests/model/onetoone/TestOneToOnePrimaryKeyJoinOptional.java @@ -0,0 +1,87 @@ +package org.tests.model.onetoone; + +import io.ebean.BaseTestCase; +import io.ebean.Ebean; +import io.ebean.Query; +import org.ebeantest.LoggedSqlCollector; +import org.junit.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TestOneToOnePrimaryKeyJoinOptional extends BaseTestCase { + + + private OtoUPrime insert(String desc) { + OtoUPrime prime = new OtoUPrime("u" + desc); + OtoUPrimeExtra extra = new OtoUPrimeExtra("v" + desc); + prime.setExtra(extra); + Ebean.save(prime); + return prime; + } + + @Test + public void insertUpdateDelete() { + + String desc = "" + System.currentTimeMillis(); + OtoUPrime p1 = insert(desc); + + assertThat(p1.getExtra().getEid()).isEqualTo(p1.getPid()).as("Same id values"); + + + Query query = Ebean.find(OtoUPrime.class).setId(p1.getPid()); + + OtoUPrime found = query.findOne(); + + assertThat(found).isNotNull(); + assertThat(sqlOf(query)).contains("select t0.pid, t0.name, t0.version, t0.pid from oto_uprime t0 where t0.pid = ?") + .as("we don't join to oto_uprime_extra"); + + assertThat(found.getName()).isEqualTo("u" + desc); + + Query queryWithFetch = Ebean.find(OtoUPrime.class) + .setId(p1.getPid()) + .fetch("extra"); + + OtoUPrime oneWith = queryWithFetch.findOne(); + + assertThat(oneWith).isNotNull(); + assertThat(sqlOf(queryWithFetch)).contains("select t0.pid, t0.name, t0.version, t1.eid, t1.extra, t1.version from oto_uprime t0 left join oto_uprime_extra t1 on t1.eid = t0.pid where t0.pid = ?") + .as("we join to oto_prime_extra"); + + + assertThat(oneWith.getExtra().getExtra()).isEqualTo("v" + desc); + + thenUpdate(oneWith); + thenDelete(found); + } + + private void thenUpdate(OtoUPrime oneWith) { + + OtoUPrimeExtra extra = oneWith.getExtra(); + extra.setExtra("modified"); + + Ebean.save(oneWith); + + extra.setExtra("mod2"); + oneWith.setName("mod2"); + + Ebean.save(oneWith); + } + + private void thenDelete(OtoUPrime found) { + + + OtoUPrime bean = Ebean.find(OtoUPrime.class, found.getPid()); + + LoggedSqlCollector.start(); + Ebean.delete(bean); + + List sql = LoggedSqlCollector.stop(); + assertThat(sql).hasSize(2); + assertThat(sql.get(0)).contains("delete from oto_uprime_extra where"); + assertThat(sql.get(1)).contains("delete from oto_uprime where"); + + } +}