diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ForcedId.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ForcedId.java index 8dd07c1ebee..e86e084da1f 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ForcedId.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ForcedId.java @@ -22,12 +22,14 @@ package ca.uhn.fhir.jpa.entity; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.ForeignKey; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Index; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; +import javax.persistence.SequenceGenerator; import javax.persistence.Table; import javax.persistence.UniqueConstraint; @@ -49,12 +51,13 @@ public class ForcedId { @Column(name = "FORCED_ID", nullable = false, length = MAX_FORCED_ID_LENGTH, updatable = false) private String myForcedId; - @GeneratedValue(strategy = GenerationType.AUTO) + @SequenceGenerator(name = "SEQ_FORCEDID_ID", sequenceName = "SEQ_FORCEDID_ID") + @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_FORCEDID_ID") @Id @Column(name = "PID") private Long myId; - @JoinColumn(name = "RESOURCE_PID", nullable = false, updatable = false) + @JoinColumn(name = "RESOURCE_PID", nullable = false, updatable = false, foreignKey=@ForeignKey(name="FK_FORCEDID_RESOURCE")) @OneToOne() private ResourceTable myResource; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceHistoryTag.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceHistoryTag.java index 5d323fe3930..5995895a922 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceHistoryTag.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceHistoryTag.java @@ -25,11 +25,13 @@ import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Embeddable; import javax.persistence.Entity; +import javax.persistence.ForeignKey; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; +import javax.persistence.SequenceGenerator; import javax.persistence.Table; @Embeddable @@ -39,13 +41,14 @@ public class ResourceHistoryTag extends BaseTag implements Serializable { private static final long serialVersionUID = 1L; - @GeneratedValue(strategy=GenerationType.AUTO) + @SequenceGenerator(name = "SEQ_HISTORYTAG_ID", sequenceName = "SEQ_HISTORYTAG_ID") + @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_HISTORYTAG_ID") @Id @Column(name = "PID") private Long myId; @ManyToOne() - @JoinColumn(name="RES_VER_PID", referencedColumnName="PID", nullable=false) + @JoinColumn(name="RES_VER_PID", referencedColumnName="PID", nullable=false, foreignKey=@ForeignKey(name="FK_HISTORYTAG_HISTORY")) private ResourceHistoryTable myResourceHistory; @Column(name = "RES_TYPE", length = ResourceTable.RESTYPE_LEN, nullable=false) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamString.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamString.java index d1f7af4e269..6c735bd91ff 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamString.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamString.java @@ -23,6 +23,7 @@ package ca.uhn.fhir.jpa.entity; import javax.persistence.Column; import javax.persistence.Embeddable; import javax.persistence.Entity; +import javax.persistence.ForeignKey; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @@ -114,7 +115,7 @@ public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchP private Long myId; @ManyToOne(optional = false) - @JoinColumn(name = "RES_ID", referencedColumnName="RES_ID", insertable=false, updatable=false) + @JoinColumn(name = "RES_ID", referencedColumnName="RES_ID", insertable=false, updatable=false, foreignKey=@ForeignKey(name="FK_SPIDXSTR_RESOURCE")) @ContainedIn private ResourceTable myResourceTable; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceLink.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceLink.java index 87eeedc85ea..5209106280d 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceLink.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceLink.java @@ -26,12 +26,14 @@ import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; +import javax.persistence.ForeignKey; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Index; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; +import javax.persistence.SequenceGenerator; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @@ -53,7 +55,8 @@ public class ResourceLink implements Serializable { private static final long serialVersionUID = 1L; - @GeneratedValue(strategy = GenerationType.AUTO) + @SequenceGenerator(name = "SEQ_RESLINK_ID", sequenceName = "SEQ_RESLINK_ID") + @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_RESLINK_ID") @Id @Column(name = "PID") private Long myId; @@ -62,7 +65,7 @@ public class ResourceLink implements Serializable { private String mySourcePath; @ManyToOne(optional = false, fetch=FetchType.LAZY) - @JoinColumn(name = "SRC_RESOURCE_ID", referencedColumnName = "RES_ID", nullable = false) + @JoinColumn(name = "SRC_RESOURCE_ID", referencedColumnName = "RES_ID", nullable = false, foreignKey=@ForeignKey(name="FK_RESLINK_SOURCE")) // @ContainedIn() private ResourceTable mySourceResource; @@ -75,7 +78,7 @@ public class ResourceLink implements Serializable { private String mySourceResourceType; @ManyToOne(optional = true, fetch=FetchType.LAZY) - @JoinColumn(name = "TARGET_RESOURCE_ID", referencedColumnName = "RES_ID", nullable = true) + @JoinColumn(name = "TARGET_RESOURCE_ID", referencedColumnName = "RES_ID", nullable = true, foreignKey=@ForeignKey(name="FK_RESLINK_TARGET")) private ResourceTable myTargetResource; @Column(name = "TARGET_RESOURCE_ID", insertable = false, updatable = false, nullable = true) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceTag.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceTag.java index 4d2c8fd2b7d..d54a10f9aeb 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceTag.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceTag.java @@ -22,11 +22,13 @@ package ca.uhn.fhir.jpa.entity; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.ForeignKey; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; +import javax.persistence.SequenceGenerator; import javax.persistence.Table; import org.apache.commons.lang3.builder.EqualsBuilder; @@ -38,13 +40,14 @@ public class ResourceTag extends BaseTag { private static final long serialVersionUID = 1L; - @GeneratedValue(strategy = GenerationType.AUTO) + @SequenceGenerator(name = "SEQ_RESTAG_ID", sequenceName = "SEQ_RESTAG_ID") + @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_RESTAG_ID") @Id @Column(name = "PID") private Long myId; @ManyToOne(cascade = {}) - @JoinColumn(name = "RES_ID", referencedColumnName = "RES_ID") + @JoinColumn(name = "RES_ID", referencedColumnName = "RES_ID", foreignKey=@ForeignKey(name="FK_RESTAG_RESOURCE")) private ResourceTable myResource; @Column(name = "RES_TYPE", length = ResourceTable.RESTYPE_LEN, nullable = false) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SubscriptionFlaggedResource.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SubscriptionFlaggedResource.java index 5374875b862..2a3e969dd25 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SubscriptionFlaggedResource.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SubscriptionFlaggedResource.java @@ -36,13 +36,13 @@ import javax.persistence.Table; public class SubscriptionFlaggedResource { @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.AUTO, generator="SEQ_SUBSCRIPTION_FLAG_ID") @SequenceGenerator(name = "SEQ_SUBSCRIPTION_FLAG_ID", sequenceName = "SEQ_SUBSCRIPTION_FLAG_ID") @Column(name = "PID", insertable = false, updatable = false) private Long myId; @ManyToOne() - @JoinColumn(name="RES_ID", nullable=false) + @JoinColumn(name="RES_ID", nullable=false, foreignKey=@ForeignKey(name="FK_SUBSFLAGRES_RES")) private ResourceTable myResource; //@formatter:off diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SubscriptionTable.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SubscriptionTable.java index 79795d0f9e0..e95860e9b78 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SubscriptionTable.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/SubscriptionTable.java @@ -64,7 +64,7 @@ public class SubscriptionTable { private Collection myFlaggedResources; @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.AUTO, generator="SEQ_SUBSCRIPTION_ID") @SequenceGenerator(name = "SEQ_SUBSCRIPTION_ID", sequenceName = "SEQ_SUBSCRIPTION_ID") @Column(name = "PID", insertable = false, updatable = false) private Long myId; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TagDefinition.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TagDefinition.java index 48abe975826..13cd45265e0 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TagDefinition.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TagDefinition.java @@ -32,6 +32,7 @@ import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; +import javax.persistence.SequenceGenerator; import javax.persistence.Table; import javax.persistence.UniqueConstraint; @@ -44,7 +45,9 @@ import ca.uhn.fhir.model.api.Tag; //@formatter:on @Entity -@Table(name = "HFJ_TAG_DEF", uniqueConstraints = { @UniqueConstraint(columnNames = { "TAG_TYPE", "TAG_SYSTEM", "TAG_CODE" }) }) +@Table(name = "HFJ_TAG_DEF", uniqueConstraints = { + @UniqueConstraint(name="IDX_TAGDEF_TYPESYSCODE", columnNames = { "TAG_TYPE", "TAG_SYSTEM", "TAG_CODE" }) +}) //@formatter:off public class TagDefinition implements Serializable { @@ -57,7 +60,8 @@ public class TagDefinition implements Serializable { private String myDisplay; @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.AUTO, generator="SEQ_TAGDEF_ID") + @SequenceGenerator(name = "SEQ_TAGDEF_ID", sequenceName = "SEQ_TAGDEF_ID") @Column(name = "TAG_ID") private Long myId; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermCodeSystem.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermCodeSystem.java index f46fdeb345d..9bc9a3c48d7 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermCodeSystem.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/TermCodeSystem.java @@ -24,6 +24,7 @@ import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.ForeignKey; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @@ -46,7 +47,7 @@ public class TermCodeSystem implements Serializable { private String myCodeSystemUri; @OneToOne() - @JoinColumn(name="CURRENT_VERSION_PID", referencedColumnName="PID", nullable=true) + @JoinColumn(name="CURRENT_VERSION_PID", referencedColumnName="PID", nullable=true, foreignKey=@ForeignKey(name="FK_TRMCODESYSTEM_CURVER")) private TermCodeSystemVersion myCurrentVersion; @Id() @@ -56,7 +57,7 @@ public class TermCodeSystem implements Serializable { private Long myPid; @OneToOne() - @JoinColumn(name = "RES_ID", referencedColumnName = "RES_ID", nullable = false, updatable = false) + @JoinColumn(name = "RES_ID", referencedColumnName = "RES_ID", nullable = false, updatable = false, foreignKey=@ForeignKey(name="FK_TRMCODESYSTEM_RES")) private ResourceTable myResource; @Column(name = "RES_ID", insertable=false, updatable=false) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java index 3cd2bcaebb4..3c9c9235cb4 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/TestUtil.java @@ -1,8 +1,12 @@ package ca.uhn.fhir.jpa.util; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + import java.io.IOException; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; +import java.util.HashSet; +import java.util.Set; import javax.persistence.*; @@ -28,6 +32,7 @@ public class TestUtil { */ public static void scanEntities(String packageName) throws IOException, ClassNotFoundException { ImmutableSet classes = ClassPath.from(TestUtil.class.getClassLoader()).getTopLevelClasses(packageName); + Set names = new HashSet(); if (classes.size() <= 1) { throw new InternalErrorException("Found no classes"); @@ -42,45 +47,52 @@ public class TestUtil { ourLog.info("Scanning: {}", clazz.getSimpleName()); - scan(clazz); + scan(clazz, names); - for (Field nextField : clazz.getFields()) { - scan(nextField); + for (Field nextField : clazz.getDeclaredFields()) { + ourLog.info(" * Scanning field: {}", nextField.getName()); + scan(nextField, names); } } } - private static void scan(AnnotatedElement ae) { + private static void scan(AnnotatedElement ae, Set theNames) { Table table = ae.getAnnotation(Table.class); if (table != null) { - assertThat(table.name()); + assertThat(table.name(), theNames); for (UniqueConstraint nextConstraint : table.uniqueConstraints()) { - assertThat(nextConstraint.name()); + assertThat(nextConstraint.name(), theNames); + Validate.isTrue(nextConstraint.name().startsWith("IDX_"), nextConstraint.name() + " must start with IDX_"); } for (Index nextConstraint : table.indexes()) { - assertThat(nextConstraint.name()); + assertThat(nextConstraint.name(), theNames); + Validate.isTrue(nextConstraint.name().startsWith("IDX_"), nextConstraint.name() + " must start with IDX_"); } } JoinColumn joinColumn = ae.getAnnotation(JoinColumn.class); if (joinColumn != null) { - assertThat(joinColumn.name()); + assertThat(joinColumn.name(), null); ForeignKey fk = joinColumn.foreignKey(); - assertThat(fk.name()); + Validate.notNull(fk); + Validate.isTrue(isNotBlank(fk.name())); + Validate.isTrue(fk.name().startsWith("FK_")); + assertThat(fk.name(), theNames); } Column column = ae.getAnnotation(Column.class); if (column != null) { - assertThat(column.name()); + assertThat(column.name(), null); } GeneratedValue gen = ae.getAnnotation(GeneratedValue.class); + SequenceGenerator sg = ae.getAnnotation(SequenceGenerator.class); + Validate.isTrue((gen != null) == (sg != null)); if (gen != null) { - assertThat(gen.generator()); - SequenceGenerator sg = ae.getAnnotation(SequenceGenerator.class); - assertThat(sg.name()); - assertThat(sg.sequenceName()); + assertThat(gen.generator(), theNames); + assertThat(sg.name(), null); + assertThat(sg.sequenceName(), null); assertEquals(gen.generator(), sg.name()); assertEquals(gen.generator(), sg.sequenceName()); } @@ -91,8 +103,11 @@ public class TestUtil { Validate.isTrue(theGenerator.equals(theName)); } - private static void assertThat(String theName) { + private static void assertThat(String theName, Set theNames) { Validate.isTrue(theName.length() <= MAX_LENGTH, "Identifier \"" + theName + "\" is " + theName.length() + " chars long"); + if (theNames != null) { + Validate.isTrue(theNames.add(theName), "Duplicate name: " + theName); + } } }