001/* 002 * #%L 003 * HAPI FHIR JPA Server 004 * %% 005 * Copyright (C) 2014 - 2025 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.jpa.entity; 021 022import ca.uhn.fhir.jpa.model.entity.BasePartitionable; 023import ca.uhn.fhir.jpa.model.entity.IdAndPartitionId; 024import ca.uhn.fhir.util.ValidateUtil; 025import jakarta.annotation.Nonnull; 026import jakarta.persistence.Column; 027import jakarta.persistence.Entity; 028import jakarta.persistence.FetchType; 029import jakarta.persistence.ForeignKey; 030import jakarta.persistence.GeneratedValue; 031import jakarta.persistence.GenerationType; 032import jakarta.persistence.Id; 033import jakarta.persistence.IdClass; 034import jakarta.persistence.Index; 035import jakarta.persistence.JoinColumn; 036import jakarta.persistence.JoinColumns; 037import jakarta.persistence.ManyToOne; 038import jakarta.persistence.PrePersist; 039import jakarta.persistence.SequenceGenerator; 040import jakarta.persistence.Table; 041import org.apache.commons.lang3.builder.ToStringBuilder; 042import org.apache.commons.lang3.builder.ToStringStyle; 043import org.hibernate.Length; 044 045import java.io.Serializable; 046import java.util.Objects; 047 048import static org.apache.commons.lang3.StringUtils.left; 049import static org.apache.commons.lang3.StringUtils.length; 050 051@Entity 052@Table( 053 name = "TRM_CONCEPT_DESIG", 054 uniqueConstraints = {}, 055 indexes = { 056 // must have same name that indexed FK or SchemaMigrationTest complains because H2 sets this index 057 // automatically 058 @Index(name = "FK_CONCEPTDESIG_CONCEPT", columnList = "CONCEPT_PID", unique = false), 059 @Index(name = "FK_CONCEPTDESIG_CSV", columnList = "CS_VER_PID") 060 }) 061@IdClass(IdAndPartitionId.class) 062public class TermConceptDesignation extends BasePartitionable implements Serializable { 063 private static final long serialVersionUID = 1L; 064 065 public static final int MAX_LENGTH = 500; 066 public static final int MAX_VAL_LENGTH = 2000; 067 068 @ManyToOne(fetch = FetchType.LAZY) 069 @JoinColumns( 070 value = { 071 @JoinColumn( 072 name = "CONCEPT_PID", 073 referencedColumnName = "PID", 074 insertable = false, 075 updatable = false, 076 nullable = false), 077 @JoinColumn( 078 name = "PARTITION_ID", 079 referencedColumnName = "PARTITION_ID", 080 insertable = false, 081 updatable = false, 082 nullable = false) 083 }, 084 foreignKey = @ForeignKey(name = "FK_CONCEPTDESIG_CONCEPT")) 085 private TermConcept myConcept; 086 087 @Column(name = "CONCEPT_PID", insertable = true, updatable = true, nullable = false) 088 private Long myConceptPid; 089 090 @Id() 091 @SequenceGenerator(name = "SEQ_CONCEPT_DESIG_PID", sequenceName = "SEQ_CONCEPT_DESIG_PID") 092 @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CONCEPT_DESIG_PID") 093 @Column(name = "PID") 094 private Long myId; 095 096 @Column(name = "LANG", nullable = true, length = MAX_LENGTH) 097 private String myLanguage; 098 099 @Column(name = "USE_SYSTEM", nullable = true, length = MAX_LENGTH) 100 private String myUseSystem; 101 102 @Column(name = "USE_CODE", nullable = true, length = MAX_LENGTH) 103 private String myUseCode; 104 105 @Column(name = "USE_DISPLAY", nullable = true, length = MAX_LENGTH) 106 private String myUseDisplay; 107 108 @Column(name = "VAL", nullable = true, length = MAX_VAL_LENGTH) 109 private String myValue; 110 111 @Column(name = "VAL_VC", nullable = true, length = Length.LONG32) 112 private String myValueVc; 113 /** 114 * TODO: Make this non-null 115 * 116 * @since 3.5.0 117 */ 118 @ManyToOne(fetch = FetchType.LAZY) 119 @JoinColumns( 120 value = { 121 @JoinColumn( 122 name = "CS_VER_PID", 123 insertable = true, 124 updatable = false, 125 nullable = false, 126 referencedColumnName = "PID"), 127 @JoinColumn( 128 name = "PARTITION_ID", 129 referencedColumnName = "PARTITION_ID", 130 insertable = true, 131 updatable = false, 132 nullable = false) 133 }, 134 foreignKey = @ForeignKey(name = "FK_CONCEPTDESIG_CSV")) 135 private TermCodeSystemVersion myCodeSystemVersion; 136 137 public String getLanguage() { 138 return myLanguage; 139 } 140 141 public TermConceptDesignation setLanguage(String theLanguage) { 142 ValidateUtil.isNotTooLongOrThrowIllegalArgument( 143 theLanguage, 144 MAX_LENGTH, 145 "Language exceeds maximum length (" + MAX_LENGTH + "): " + length(theLanguage)); 146 myLanguage = theLanguage; 147 return this; 148 } 149 150 public String getUseCode() { 151 return myUseCode; 152 } 153 154 public TermConceptDesignation setUseCode(String theUseCode) { 155 ValidateUtil.isNotTooLongOrThrowIllegalArgument( 156 theUseCode, MAX_LENGTH, "Use code exceeds maximum length (" + MAX_LENGTH + "): " + length(theUseCode)); 157 myUseCode = theUseCode; 158 return this; 159 } 160 161 public String getUseDisplay() { 162 return myUseDisplay; 163 } 164 165 public TermConceptDesignation setUseDisplay(String theUseDisplay) { 166 myUseDisplay = left(theUseDisplay, MAX_LENGTH); 167 return this; 168 } 169 170 public String getUseSystem() { 171 return myUseSystem; 172 } 173 174 public TermConceptDesignation setUseSystem(String theUseSystem) { 175 ValidateUtil.isNotTooLongOrThrowIllegalArgument( 176 theUseSystem, 177 MAX_LENGTH, 178 "Use system exceeds maximum length (" + MAX_LENGTH + "): " + length(theUseSystem)); 179 myUseSystem = theUseSystem; 180 return this; 181 } 182 183 public String getValue() { 184 return Objects.nonNull(myValueVc) ? myValueVc : myValue; 185 } 186 187 public TermConceptDesignation setValue(@Nonnull String theValueVc) { 188 myValueVc = theValueVc; 189 return this; 190 } 191 192 public TermConceptDesignation setCodeSystemVersion(TermCodeSystemVersion theCodeSystemVersion) { 193 myCodeSystemVersion = theCodeSystemVersion; 194 return this; 195 } 196 197 public TermConceptDesignation setConcept(TermConcept theConcept) { 198 myConcept = theConcept; 199 myConceptPid = theConcept.getId(); 200 setPartitionId(theConcept.getPartitionId()); 201 return this; 202 } 203 204 @PrePersist 205 public void prePersist() { 206 if (myConceptPid == null) { 207 myConceptPid = myConcept.getId(); 208 assert myConceptPid != null; 209 } 210 } 211 212 public Long getPid() { 213 return myId; 214 } 215 216 public IdAndPartitionId getPartitionedId() { 217 return IdAndPartitionId.forId(myId, this); 218 } 219 220 @Override 221 public String toString() { 222 return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) 223 .append("conceptPid", myConcept.getId()) 224 .append("pid", myId) 225 .append("language", myLanguage) 226 .append("useSystem", myUseSystem) 227 .append("useCode", myUseCode) 228 .append("useDisplay", myUseDisplay) 229 .append("value", myValue) 230 .toString(); 231 } 232 233 public Long getId() { 234 return myId; 235 } 236}