
001package ca.uhn.fhir.jpa.entity; 002 003/*- 004 * #%L 005 * HAPI FHIR JPA Server 006 * %% 007 * Copyright (C) 2014 - 2022 Smile CDR, Inc. 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import ca.uhn.fhir.jpa.model.entity.BasePartitionable; 024import ca.uhn.fhir.jpa.model.entity.ResourceTable; 025import ca.uhn.fhir.mdm.api.IMdmLink; 026import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum; 027import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; 028import org.apache.commons.lang3.builder.ToStringBuilder; 029 030import javax.persistence.Column; 031import javax.persistence.Entity; 032import javax.persistence.EnumType; 033import javax.persistence.Enumerated; 034import javax.persistence.FetchType; 035import javax.persistence.ForeignKey; 036import javax.persistence.GeneratedValue; 037import javax.persistence.GenerationType; 038import javax.persistence.Id; 039import javax.persistence.Index; 040import javax.persistence.JoinColumn; 041import javax.persistence.ManyToOne; 042import javax.persistence.SequenceGenerator; 043import javax.persistence.Table; 044import javax.persistence.Temporal; 045import javax.persistence.TemporalType; 046import javax.persistence.UniqueConstraint; 047import java.util.Date; 048 049@Entity 050@Table(name = "MPI_LINK", uniqueConstraints = { 051 // TODO GGG DROP this index, and instead use the below one 052 @UniqueConstraint(name = "IDX_EMPI_PERSON_TGT", columnNames = {"PERSON_PID", "TARGET_PID"}), 053 // v---- this one 054 //TODO GGG revisit adding this: @UniqueConstraint(name = "IDX_EMPI_GR_TGT", columnNames = {"GOLDEN_RESOURCE_PID", "TARGET_PID"}), 055 //TODO GGG Should i make individual indices for PERSON/TARGET? 056}, indexes = { 057 @Index(name = "IDX_EMPI_MATCH_TGT_VER", columnList = "MATCH_RESULT, TARGET_PID, VERSION") 058}) 059public class MdmLink extends BasePartitionable implements IMdmLink { 060 public static final int VERSION_LENGTH = 16; 061 private static final int MATCH_RESULT_LENGTH = 16; 062 private static final int LINK_SOURCE_LENGTH = 16; 063 public static final int SOURCE_TYPE_LENGTH = 40; 064 065 @SequenceGenerator(name = "SEQ_EMPI_LINK_ID", sequenceName = "SEQ_EMPI_LINK_ID") 066 @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_EMPI_LINK_ID") 067 @Id 068 @Column(name = "PID") 069 private Long myId; 070 071 @ManyToOne(optional = false, fetch = FetchType.LAZY, cascade = {}) 072 @JoinColumn(name = "GOLDEN_RESOURCE_PID", referencedColumnName = "RES_ID", foreignKey = @ForeignKey(name = "FK_EMPI_LINK_GOLDEN_RESOURCE"), insertable=false, updatable=false, nullable=false) 073 private ResourceTable myGoldenResource; 074 075 @Column(name = "GOLDEN_RESOURCE_PID", nullable=false) 076 private Long myGoldenResourcePid; 077 078 @Deprecated 079 @ManyToOne(optional = false, fetch = FetchType.LAZY, cascade = {}) 080 @JoinColumn(name = "PERSON_PID", referencedColumnName = "RES_ID", foreignKey = @ForeignKey(name = "FK_EMPI_LINK_PERSON"), insertable=false, updatable=false, nullable=false) 081 private ResourceTable myPerson; 082 083 @Deprecated 084 @Column(name = "PERSON_PID", nullable=false) 085 private Long myPersonPid; 086 087 @ManyToOne(optional = false, fetch = FetchType.LAZY, cascade = {}) 088 @JoinColumn(name = "TARGET_PID", referencedColumnName = "RES_ID", foreignKey = @ForeignKey(name = "FK_EMPI_LINK_TARGET"), insertable=false, updatable=false, nullable=false) 089 private ResourceTable mySource; 090 091 @Column(name = "TARGET_PID", updatable=false, nullable=false) 092 private Long mySourcePid; 093 094 @Column(name = "MATCH_RESULT", nullable = false) 095 @Enumerated(EnumType.ORDINAL) 096 private MdmMatchResultEnum myMatchResult; 097 098 @Column(name = "LINK_SOURCE", nullable = false) 099 @Enumerated(EnumType.ORDINAL) 100 private MdmLinkSourceEnum myLinkSource; 101 102 @Temporal(TemporalType.TIMESTAMP) 103 @Column(name = "CREATED", nullable = false) 104 private Date myCreated; 105 106 @Temporal(TemporalType.TIMESTAMP) 107 @Column(name = "UPDATED", nullable = false) 108 private Date myUpdated; 109 110 @Column(name = "VERSION", nullable = false, length = VERSION_LENGTH) 111 private String myVersion; 112 113 /** This link was created as a result of an eid match **/ 114 @Column(name = "EID_MATCH") 115 private Boolean myEidMatch; 116 117 /** This link created a new person **/ 118 @Column(name = "NEW_PERSON") 119 private Boolean myHadToCreateNewGoldenResource; 120 121 @Column(name = "VECTOR") 122 private Long myVector; 123 124 @Column(name = "SCORE") 125 private Double myScore; 126 127 //TODO GGG GL-1340 128 @Column(name = "RULE_COUNT") 129 private Long myRuleCount; 130 131 public MdmLink() {} 132 133 public MdmLink(String theVersion) { 134 myVersion = theVersion; 135 } 136 137 @Column(name = "TARGET_TYPE", nullable = true, length = SOURCE_TYPE_LENGTH) 138 private String myMdmSourceType; 139 140 public Long getId() { 141 return myId; 142 } 143 144 public MdmLink setId(Long theId) { 145 myId = theId; 146 return this; 147 } 148 149 public ResourceTable getGoldenResource() { 150 return myGoldenResource; 151 } 152 153 public MdmLink setGoldenResource(ResourceTable theGoldenResource) { 154 myGoldenResource = theGoldenResource; 155 myGoldenResourcePid = theGoldenResource.getId(); 156 157 myPerson = theGoldenResource; 158 myPersonPid = theGoldenResource.getId(); 159 160 return this; 161 } 162 163 public Long getGoldenResourcePid() { 164 return myGoldenResourcePid; 165 } 166 167 /** 168 * @deprecated Use {@link #setGoldenResourcePid(Long)} instead 169 */ 170 @Deprecated 171 public MdmLink setPersonPid(Long thePersonPid) { 172 myPersonPid = thePersonPid; 173 return this; 174 } 175 176 public MdmLink setGoldenResourcePid(Long theGoldenResourcePid) { 177 setPersonPid(theGoldenResourcePid); 178 179 myGoldenResourcePid = theGoldenResourcePid; 180 return this; 181 } 182 183 public ResourceTable getSource() { 184 return mySource; 185 } 186 187 public MdmLink setSource(ResourceTable theSource) { 188 mySource = theSource; 189 mySourcePid = theSource.getId(); 190 return this; 191 } 192 193 public Long getSourcePid() { 194 return mySourcePid; 195 } 196 197 public MdmLink setSourcePid(Long theSourcePid) { 198 mySourcePid = theSourcePid; 199 return this; 200 } 201 202 public MdmMatchResultEnum getMatchResult() { 203 return myMatchResult; 204 } 205 206 public MdmLink setMatchResult(MdmMatchResultEnum theMatchResult) { 207 myMatchResult = theMatchResult; 208 return this; 209 } 210 211 public boolean isNoMatch() { 212 return myMatchResult == MdmMatchResultEnum.NO_MATCH; 213 } 214 215 public boolean isMatch() { 216 return myMatchResult == MdmMatchResultEnum.MATCH; 217 } 218 219 public boolean isPossibleMatch() { 220 return myMatchResult == MdmMatchResultEnum.POSSIBLE_MATCH; 221 } 222 223 public boolean isRedirect() { 224 return myMatchResult == MdmMatchResultEnum.REDIRECT; 225 } 226 227 public boolean isPossibleDuplicate() { 228 return myMatchResult == MdmMatchResultEnum.POSSIBLE_DUPLICATE; 229 } 230 231 public MdmLinkSourceEnum getLinkSource() { 232 return myLinkSource; 233 } 234 235 public MdmLink setLinkSource(MdmLinkSourceEnum theLinkSource) { 236 myLinkSource = theLinkSource; 237 return this; 238 } 239 240 public boolean isAuto() { 241 return myLinkSource == MdmLinkSourceEnum.AUTO; 242 } 243 244 public boolean isManual() { 245 return myLinkSource == MdmLinkSourceEnum.MANUAL; 246 } 247 248 public Date getCreated() { 249 return myCreated; 250 } 251 252 public MdmLink setCreated(Date theCreated) { 253 myCreated = theCreated; 254 return this; 255 } 256 257 public Date getUpdated() { 258 return myUpdated; 259 } 260 261 public MdmLink setUpdated(Date theUpdated) { 262 myUpdated = theUpdated; 263 return this; 264 } 265 266 public String getVersion() { 267 return myVersion; 268 } 269 270 public MdmLink setVersion(String theVersion) { 271 myVersion = theVersion; 272 return this; 273 } 274 275 public Long getVector() { 276 return myVector; 277 } 278 279 public MdmLink setVector(Long theVector) { 280 myVector = theVector; 281 return this; 282 } 283 284 public Double getScore() { 285 return myScore; 286 } 287 288 public MdmLink setScore(Double theScore) { 289 myScore = theScore; 290 return this; 291 } 292 293 public Boolean getEidMatch() { 294 return myEidMatch; 295 } 296 297 /** 298 * Note that this method can not be called <code>getEidMatch</code> or 299 * <code>isEidMatch</code> because Hibernate Search complains about having 300 * 2 accessors for this property 301 */ 302 public boolean isEidMatchPresent() { 303 return myEidMatch != null && myEidMatch; 304 } 305 306 public MdmLink setEidMatch(Boolean theEidMatch) { 307 myEidMatch = theEidMatch; 308 return this; 309 } 310 311 public boolean getHadToCreateNewGoldenResource() { 312 return myHadToCreateNewGoldenResource != null && myHadToCreateNewGoldenResource; 313 } 314 315 public MdmLink setHadToCreateNewGoldenResource(Boolean theHadToCreateNewResource) { 316 myHadToCreateNewGoldenResource = theHadToCreateNewResource; 317 return this; 318 } 319 320 public MdmLink setMdmSourceType(String mdmSourceType) { 321 myMdmSourceType = mdmSourceType; 322 return this; 323 } 324 325 @Override 326 public String toString() { 327 return new ToStringBuilder(this) 328 .append("myId", myId) 329 .append("myGoldenResource", myGoldenResourcePid) 330 .append("mySourcePid", mySourcePid) 331 .append("myMdmSourceType", myMdmSourceType) 332 .append("myMatchResult", myMatchResult) 333 .append("myLinkSource", myLinkSource) 334 .append("myEidMatch", myEidMatch) 335 .append("myHadToCreateNewResource", myHadToCreateNewGoldenResource) 336 .append("myScore", myScore) 337 .append("myRuleCount", myRuleCount) 338 .append("myPartitionId", getPartitionId()) 339 .toString(); 340 } 341 342 public String getMdmSourceType() { 343 return myMdmSourceType; 344 } 345 346 public Long getRuleCount() { 347 return myRuleCount; 348 } 349 350 public void setRuleCount(Long theRuleCount) { 351 myRuleCount = theRuleCount; 352 } 353 354}