Improve the error message thrown by JPA server

This commit is contained in:
James Agnew 2018-05-11 17:03:48 -04:00
parent 38e6edf4ae
commit f1ba0016b2
33 changed files with 527 additions and 366 deletions

View File

@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.cds.example;
import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu3; import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu3;
import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory; import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory;
import ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect;
import ca.uhn.fhir.jpa.util.SubscriptionsRequireManualActivationInterceptorDstu3; import ca.uhn.fhir.jpa.util.SubscriptionsRequireManualActivationInterceptorDstu3;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor; import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor;
@ -59,18 +60,16 @@ public class FhirServerConfig extends BaseJavaConfigDstu3 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = entityManagerFactory();
retVal.setPersistenceUnitName("HAPI_PU"); retVal.setPersistenceUnitName("HAPI_PU");
retVal.setDataSource(dataSource()); retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(jpaProperties()); retVal.setJpaProperties(jpaProperties());
return retVal; return retVal;
} }
private Properties jpaProperties() { private Properties jpaProperties() {
Properties extraProperties = new Properties(); Properties extraProperties = new Properties();
extraProperties.put("hibernate.dialect", org.hibernate.dialect.DerbyTenSevenDialect.class.getName()); extraProperties.put("hibernate.dialect", DerbyTenSevenHapiFhirDialect.class.getName());
extraProperties.put("hibernate.format_sql", "true"); extraProperties.put("hibernate.format_sql", "true");
extraProperties.put("hibernate.show_sql", "false"); extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update"); extraProperties.put("hibernate.hbm2ddl.auto", "update");

View File

@ -6,6 +6,9 @@ import java.util.Properties;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource; import javax.sql.DataSource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.config.BaseConfig;
import ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect;
import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
import org.hibernate.jpa.HibernatePersistenceProvider; import org.hibernate.jpa.HibernatePersistenceProvider;
@ -29,7 +32,7 @@ import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
public class FhirServerConfigCommon { public class FhirServerConfigCommon {
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(FhirServerConfigCommon.class); private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(FhirServerConfigCommon.class);
/** /**
* Configure FHIR properties around the the JPA server via this bean * Configure FHIR properties around the the JPA server via this bean
*/ */
@ -84,14 +87,14 @@ public class FhirServerConfigCommon {
return dataSource; return dataSource;
} }
public static LocalContainerEntityManagerFactoryBean getEntityManagerFactory(Environment env, DataSource dataSource) { public static LocalContainerEntityManagerFactoryBean getEntityManagerFactory(Environment env, DataSource dataSource, FhirContext theCtx) {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean();
BaseConfig.configureEntityManagerFactory(retVal, theCtx);
retVal.setPersistenceUnitName("HAPI_PU"); retVal.setPersistenceUnitName("HAPI_PU");
retVal.setDataSource(dataSource); retVal.setDataSource(dataSource);
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(jpaProperties(env)); retVal.setJpaProperties(jpaProperties(env));
return retVal; return retVal;
} }
@ -134,7 +137,7 @@ public class FhirServerConfigCommon {
extraProperties.put("hibernate.dialect", org.hibernate.dialect.PostgreSQL9Dialect.class.getName()); extraProperties.put("hibernate.dialect", org.hibernate.dialect.PostgreSQL9Dialect.class.getName());
} }
else if(dbUrl != null && dbUrl.indexOf("derby") > -1) { else if(dbUrl != null && dbUrl.indexOf("derby") > -1) {
extraProperties.put("hibernate.dialect", org.hibernate.dialect.DerbyTenSevenDialect.class.getName()); extraProperties.put("hibernate.dialect", DerbyTenSevenHapiFhirDialect.class.getName());
} }
boolean hibernateCreate = new Boolean(env.getProperty(Utils.HIBERNATE_CREATE)); boolean hibernateCreate = new Boolean(env.getProperty(Utils.HIBERNATE_CREATE));
logger.info("------DB hibernateCreate: " + hibernateCreate); logger.info("------DB hibernateCreate: " + hibernateCreate);

View File

@ -57,6 +57,8 @@ ca.uhn.fhir.validation.ValidationResult.noIssuesDetected=No issues detected duri
# JPA Messages # JPA Messages
ca.uhn.fhir.jpa.config.HapiFhirHibernateJpaDialect.resourceVersionConstraintFailure=The operation has failed with a version constraint failure. This generally means that two clients/threads were trying to update the same resource at the same time, and this request was chosen as the failing request.
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.externalReferenceNotAllowed=Resource contains external reference to URL "{0}" but this server is not configured to allow external references ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.externalReferenceNotAllowed=Resource contains external reference to URL "{0}" but this server is not configured to allow external references
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.incomingNoopInTransaction=Transaction contains resource with operation NOOP. This is only valid as a response operation, not in a request ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.incomingNoopInTransaction=Transaction contains resource with operation NOOP. This is only valid as a response operation, not in a request
ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.invalidMatchUrlInvalidResourceType=Invalid match URL "{0}" - Unknown resource type: "{1}" ca.uhn.fhir.jpa.dao.BaseHapiFhirDao.invalidMatchUrlInvalidResourceType=Invalid match URL "{0}" - Unknown resource type: "{1}"

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.cli;
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -26,10 +26,7 @@ import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.client.api.IGenericClient; import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.client.interceptor.SimpleRequestHeaderInterceptor; import ca.uhn.fhir.rest.client.interceptor.SimpleRequestHeaderInterceptor;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.*;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream; import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
@ -57,9 +54,6 @@ import java.util.zip.GZIPInputStream;
import static org.apache.commons.lang3.StringUtils.*; import static org.apache.commons.lang3.StringUtils.*;
public abstract class BaseCommand implements Comparable<BaseCommand> { public abstract class BaseCommand implements Comparable<BaseCommand> {
// TODO: Don't use qualified names for loggers in HAPI CLI.
private static final Logger ourLog = LoggerFactory.getLogger(BaseCommand.class);
protected static final String BASE_URL_PARAM = "t"; protected static final String BASE_URL_PARAM = "t";
protected static final String BASE_URL_PARAM_LONGOPT = "target"; protected static final String BASE_URL_PARAM_LONGOPT = "target";
protected static final String BASE_URL_PARAM_NAME = "target"; protected static final String BASE_URL_PARAM_NAME = "target";
@ -78,8 +72,8 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
protected static final String VERBOSE_LOGGING_PARAM = "l"; protected static final String VERBOSE_LOGGING_PARAM = "l";
protected static final String VERBOSE_LOGGING_PARAM_LONGOPT = "logging"; protected static final String VERBOSE_LOGGING_PARAM_LONGOPT = "logging";
protected static final String VERBOSE_LOGGING_PARAM_DESC = "If specified, verbose logging will be used."; protected static final String VERBOSE_LOGGING_PARAM_DESC = "If specified, verbose logging will be used.";
// TODO: Don't use qualified names for loggers in HAPI CLI.
private static final Logger ourLog = LoggerFactory.getLogger(BaseCommand.class);
protected FhirContext myFhirCtx; protected FhirContext myFhirCtx;
public BaseCommand() { public BaseCommand() {
@ -104,13 +98,8 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
addRequiredOption(theOptions, FHIR_VERSION_PARAM, FHIR_VERSION_PARAM_LONGOPT, FHIR_VERSION_PARAM_NAME, FHIR_VERSION_PARAM_DESC + versions); addRequiredOption(theOptions, FHIR_VERSION_PARAM, FHIR_VERSION_PARAM_LONGOPT, FHIR_VERSION_PARAM_NAME, FHIR_VERSION_PARAM_DESC + versions);
} }
protected void addVerboseLoggingOption(Options theOptions) { private void addOption(Options theOptions, OptionGroup theOptionGroup, boolean theRequired, String theOpt, String theLongOpt, boolean theHasArgument, String theArgumentName, String theDescription) {
addOptionalOption(theOptions, VERBOSE_LOGGING_PARAM, VERBOSE_LOGGING_PARAM_LONGOPT, false, VERBOSE_LOGGING_PARAM_DESC); Option option = createOption(theRequired, theOpt, theLongOpt, theHasArgument, theDescription);
}
private void addOption(Options theOptions, boolean theRequired, String theOpt, String theLong, boolean theHasArgument, String theArgumentName, String theDescription) {
Option option = new Option(theOpt, theLong, theHasArgument, theDescription);
option.setRequired(theRequired);
if (theHasArgument && isNotBlank(theArgumentName)) { if (theHasArgument && isNotBlank(theArgumentName)) {
option.setArgName(theArgumentName); option.setArgName(theArgumentName);
} }
@ -119,30 +108,48 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
if (theOptions.getOption(theOpt) != null) { if (theOptions.getOption(theOpt) != null) {
throw new IllegalStateException("Duplicate option: " + theOpt); throw new IllegalStateException("Duplicate option: " + theOpt);
} }
if (theOptionGroup != null && theOptionGroup.getOptions().stream().anyMatch(t-> theOpt.equals(t.getOpt()))) {
throw new IllegalStateException("Duplicate option: " + theOpt);
}
} }
if (isNotBlank(theLong)) { if (isNotBlank(theLongOpt)) {
if (theOptions.getOption(theLong) != null) { if (theOptions.getOption(theLongOpt) != null) {
throw new IllegalStateException("Duplicate option: " + theLong); throw new IllegalStateException("Duplicate option: " + theLongOpt);
}
if (theOptionGroup != null && theOptionGroup.getOptions().stream().anyMatch(t-> theLongOpt.equals(t.getLongOpt()))) {
throw new IllegalStateException("Duplicate option: " + theOpt);
} }
} }
theOptions.addOption(option); if (theOptionGroup != null) {
theOptionGroup.addOption(option);
} else {
theOptions.addOption(option);
}
} }
protected void addOptionalOption(Options theOptions, String theOpt, String theLong, boolean theTakesArgument, String theDescription) { protected void addOptionalOption(Options theOptions, String theOpt, String theLong, boolean theTakesArgument, String theDescription) {
addOption(theOptions, false, theOpt, theLong, theTakesArgument, null, theDescription); addOption(theOptions, null, false, theOpt, theLong, theTakesArgument, null, theDescription);
} }
protected void addOptionalOption(Options theOptions, String theOpt, String theLong, String theArgumentName, String theDescription) { protected void addOptionalOption(Options theOptions, String theOpt, String theLong, String theArgumentName, String theDescription) {
addOption(theOptions, false, theOpt, theLong, isNotBlank(theArgumentName), theArgumentName, theDescription); addOption(theOptions, null, false, theOpt, theLong, isNotBlank(theArgumentName), theArgumentName, theDescription);
}
protected void addOptionalOption(Options theOptions, OptionGroup theOptionGroup, String theOpt, String theLong, String theArgumentName, String theDescription) {
addOption(theOptions, theOptionGroup, false, theOpt, theLong, isNotBlank(theArgumentName), theArgumentName, theDescription);
} }
protected void addRequiredOption(Options theOptions, String theOpt, String theLong, boolean theTakesArgument, String theDescription) { protected void addRequiredOption(Options theOptions, String theOpt, String theLong, boolean theTakesArgument, String theDescription) {
addOption(theOptions, true, theOpt, theLong, theTakesArgument, null, theDescription); addOption(theOptions, null, true, theOpt, theLong, theTakesArgument, null, theDescription);
} }
protected void addRequiredOption(Options theOptions, String theOpt, String theLong, String theArgumentName, String theDescription) { protected void addRequiredOption(Options theOptions, String theOpt, String theLong, String theArgumentName, String theDescription) {
addOption(theOptions, true, theOpt, theLong, isNotBlank(theArgumentName), theArgumentName, theDescription); addOption(theOptions, null, true, theOpt, theLong, isNotBlank(theArgumentName), theArgumentName, theDescription);
}
protected void addVerboseLoggingOption(Options theOptions) {
addOptionalOption(theOptions, VERBOSE_LOGGING_PARAM, VERBOSE_LOGGING_PARAM_LONGOPT, false, VERBOSE_LOGGING_PARAM_DESC);
} }
@Override @Override
@ -150,6 +157,12 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
return getCommandName().compareTo(theO.getCommandName()); return getCommandName().compareTo(theO.getCommandName());
} }
private Option createOption(boolean theRequired, String theOpt, String theLong, boolean theHasArgument, String theDescription) {
Option option = new Option(theOpt, theLong, theHasArgument, theDescription);
option.setRequired(theRequired);
return option;
}
protected Reader createReader(File theInputFile) throws IOException { protected Reader createReader(File theInputFile) throws IOException {
InputStream inputStream = new FileInputStream(theInputFile); InputStream inputStream = new FileInputStream(theInputFile);
if (theInputFile.getName().toLowerCase().endsWith(".gz")) { if (theInputFile.getName().toLowerCase().endsWith(".gz")) {

View File

@ -68,18 +68,18 @@ public class ValidateCommand extends BaseCommand {
addFhirVersionOption(retVal); addFhirVersionOption(retVal);
OptionGroup source = new OptionGroup(); OptionGroup source = new OptionGroup();
addOptionalOption(source, "n", "file", true, "filename", "The name of the file to validate"); addOptionalOption(retVal, source, "n", "file", "filename", "The name of the file to validate");
addOptionalOption(source, "d", "data", true, "text", "The text to validate"); addOptionalOption(retVal, source, "d", "data", "text", "The text to validate");
retVal.addOptionGroup(source); retVal.addOptionGroup(source);
retVal.addOption("p", "profile", false, "Validate using Profiles (StructureDefinition / ValueSet)"); retVal.addOption("p", "profile", false, "Validate using Profiles (StructureDefinition / ValueSet)");
retVal.addOption("r", "fetch-remote", false, retVal.addOption("r", "fetch-remote", false,
"Allow fetching remote resources (in other words, if a resource being validated refers to an external StructureDefinition, Questionnaire, etc. this flag allows the validator to access the internet to try and fetch this resource)"); "Allow fetching remote resources (in other words, if a resource being validated refers to an external StructureDefinition, Questionnaire, etc. this flag allows the validator to access the internet to try and fetch this resource)");
addOptionalOption(retVal, "l", "fetch-local", true, "filename", "Fetch a profile locally and use it if referenced")); addOptionalOption(retVal, "l", "fetch-local", "filename", "Fetch a profile locally and use it if referenced");
addOptionalOption(retVal, null, "igpack", true, "If specified, provides the filename of an IGPack file to include in validation"); addOptionalOption(retVal, null, "igpack", true, "If specified, provides the filename of an IGPack file to include in validation");
addOptionalOption(retVal, "x", "xsd", false, "Validate using Schemas"); addOptionalOption(retVal, "x", "xsd", false, "Validate using Schemas");
addOptionalOption(retVal, "s", "sch", false, "Validate using Schematrons"); addOptionalOption(retVal, "s", "sch", false, "Validate using Schematrons");
addOptionalOption(retVal, "e", "encoding", true, "encoding", "File encoding (default is UTF-8)"); addOptionalOption(retVal, "e", "encoding","encoding", "File encoding (default is UTF-8)");
return retVal; return retVal;
} }

View File

@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.demo;
import java.util.Properties; import java.util.Properties;
import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory; import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory;
import ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -15,7 +16,7 @@ public class FhirDbConfig {
@Bean() @Bean()
public Properties jpaProperties() { public Properties jpaProperties() {
Properties extraProperties = new Properties(); Properties extraProperties = new Properties();
extraProperties.put("hibernate.dialect", org.hibernate.dialect.DerbyTenSevenDialect.class.getName()); extraProperties.put("hibernate.dialect", DerbyTenSevenHapiFhirDialect.class.getName());
extraProperties.put("hibernate.format_sql", "true"); extraProperties.put("hibernate.format_sql", "true");
extraProperties.put("hibernate.show_sql", "false"); extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update"); extraProperties.put("hibernate.hbm2ddl.auto", "update");

View File

@ -65,7 +65,7 @@ public class FhirServerConfig extends BaseJavaConfigDstu2 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName("HAPI_PU"); retVal.setPersistenceUnitName("HAPI_PU");
retVal.setDataSource(dataSource()); retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity"); retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");

View File

@ -68,11 +68,9 @@ public class FhirServerConfigDstu3 extends BaseJavaConfigDstu3 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName("HAPI_PU"); retVal.setPersistenceUnitName("HAPI_PU");
retVal.setDataSource(dataSource()); retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(myJpaProperties); retVal.setJpaProperties(myJpaProperties);
return retVal; return retVal;
} }

View File

@ -68,11 +68,9 @@ public class FhirServerConfigR4 extends BaseJavaConfigR4 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName("HAPI_PU"); retVal.setPersistenceUnitName("HAPI_PU");
retVal.setDataSource(dataSource()); retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(myJpaProperties); retVal.setJpaProperties(myJpaProperties);
return retVal; return retVal;
} }

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.config;
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -20,12 +20,15 @@ package ca.uhn.fhir.jpa.config;
* #L% * #L%
*/ */
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.i18n.HapiLocalizer;
import ca.uhn.fhir.jpa.search.*; import ca.uhn.fhir.jpa.search.*;
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc; import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
import ca.uhn.fhir.jpa.sp.SearchParamPresenceSvcImpl; import ca.uhn.fhir.jpa.sp.SearchParamPresenceSvcImpl;
import ca.uhn.fhir.jpa.subscription.email.SubscriptionEmailInterceptor; import ca.uhn.fhir.jpa.subscription.email.SubscriptionEmailInterceptor;
import ca.uhn.fhir.jpa.subscription.resthook.SubscriptionRestHookInterceptor; import ca.uhn.fhir.jpa.subscription.resthook.SubscriptionRestHookInterceptor;
import ca.uhn.fhir.jpa.subscription.websocket.SubscriptionWebsocketInterceptor; import ca.uhn.fhir.jpa.subscription.websocket.SubscriptionWebsocketInterceptor;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
@ -35,6 +38,9 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.hibernate5.HibernateExceptionTranslator;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaDialect;
import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.annotation.SchedulingConfigurer;
@ -47,7 +53,7 @@ import javax.annotation.Resource;
@Configuration @Configuration
@EnableScheduling @EnableScheduling
@EnableJpaRepositories(basePackages = "ca.uhn.fhir.jpa.dao.data") @EnableJpaRepositories(basePackages = "ca.uhn.fhir.jpa.dao.data")
public class BaseConfig implements SchedulingConfigurer { public abstract class BaseConfig implements SchedulingConfigurer {
public static final String TASK_EXECUTOR_NAME = "hapiJpaTaskExecutor"; public static final String TASK_EXECUTOR_NAME = "hapiJpaTaskExecutor";
@ -67,6 +73,29 @@ public class BaseConfig implements SchedulingConfigurer {
return retVal; return retVal;
} }
/**
* This method should be overridden to provide an actual completed
* bean, but it provides a partially completed entity manager
* factory with HAPI FHIR customizations
*/
protected LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean();
configureEntityManagerFactory(retVal, fhirContext());
return retVal;
}
public abstract FhirContext fhirContext();
@Bean
public HibernateExceptionTranslator hibernateExceptionTranslator() {
return new HibernateExceptionTranslator();
}
@Bean
public HibernateJpaDialect hibernateJpaDialectIntance() {
return new HibernateJpaDialect();
}
@Bean() @Bean()
public ScheduledExecutorFactoryBean scheduledExecutorService() { public ScheduledExecutorFactoryBean scheduledExecutorService() {
ScheduledExecutorFactoryBean b = new ScheduledExecutorFactoryBean(); ScheduledExecutorFactoryBean b = new ScheduledExecutorFactoryBean();
@ -112,7 +141,7 @@ public class BaseConfig implements SchedulingConfigurer {
return new SubscriptionWebsocketInterceptor(); return new SubscriptionWebsocketInterceptor();
} }
@Bean(name=TASK_EXECUTOR_NAME) @Bean(name = TASK_EXECUTOR_NAME)
public TaskScheduler taskScheduler() { public TaskScheduler taskScheduler() {
ConcurrentTaskScheduler retVal = new ConcurrentTaskScheduler(); ConcurrentTaskScheduler retVal = new ConcurrentTaskScheduler();
retVal.setConcurrentExecutor(scheduledExecutorService().getObject()); retVal.setConcurrentExecutor(scheduledExecutorService().getObject());
@ -120,6 +149,16 @@ public class BaseConfig implements SchedulingConfigurer {
return retVal; return retVal;
} }
public static void configureEntityManagerFactory(LocalContainerEntityManagerFactoryBean theFactory, FhirContext theCtx) {
theFactory.setJpaDialect(hibernateJpaDialect(theCtx.getLocalizer()));
theFactory.setPackagesToScan("ca.uhn.fhir.jpa.entity");
theFactory.setPersistenceProvider(new HibernatePersistenceProvider());
}
private static HibernateJpaDialect hibernateJpaDialect(HapiLocalizer theLocalizer) {
return new HapiFhirHibernateJpaDialect(theLocalizer);
}
/** /**
* This lets the "@Value" fields reference properties from the properties file * This lets the "@Value" fields reference properties from the properties file
*/ */

View File

@ -53,6 +53,11 @@ public class BaseDstu2Config extends BaseConfig {
return fhirContextDstu2(); return fhirContextDstu2();
} }
@Override
public FhirContext fhirContext() {
return fhirContextDstu2();
}
@Bean(name = "myFhirContextDstu2") @Bean(name = "myFhirContextDstu2")
@Lazy @Lazy
public FhirContext fhirContextDstu2() { public FhirContext fhirContextDstu2() {

View File

@ -0,0 +1,33 @@
package ca.uhn.fhir.jpa.config;
import ca.uhn.fhir.i18n.HapiLocalizer;
import ca.uhn.fhir.jpa.entity.ResourceHistoryTable;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import org.hibernate.HibernateException;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.jpa.vendor.HibernateJpaDialect;
public class HapiFhirHibernateJpaDialect extends HibernateJpaDialect {
private HapiLocalizer myLocalizer;
/**
* Constructor
*/
public HapiFhirHibernateJpaDialect(HapiLocalizer theLocalizer) {
myLocalizer = theLocalizer;
}
@Override
protected DataAccessException convertHibernateAccessException(HibernateException theException) {
if (theException instanceof ConstraintViolationException) {
if (ResourceHistoryTable.IDX_RESVER_ID_VER.equals(((ConstraintViolationException) theException).getConstraintName())) {
throw new PreconditionFailedException(myLocalizer.getMessage(HapiFhirHibernateJpaDialect.class, "resourceVersionConstraintFailure"));
}
}
return super.convertHibernateAccessException(theException);
}
}

View File

@ -15,7 +15,6 @@ import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;
import ca.uhn.fhir.jpa.term.IHapiTerminologySvcDstu3; import ca.uhn.fhir.jpa.term.IHapiTerminologySvcDstu3;
import ca.uhn.fhir.jpa.term.TerminologyLoaderSvcImpl; import ca.uhn.fhir.jpa.term.TerminologyLoaderSvcImpl;
import ca.uhn.fhir.jpa.util.ResourceCountCache; import ca.uhn.fhir.jpa.util.ResourceCountCache;
import ca.uhn.fhir.jpa.util.SingleItemLoadingCache;
import ca.uhn.fhir.jpa.validation.JpaValidationSupportChainDstu3; import ca.uhn.fhir.jpa.validation.JpaValidationSupportChainDstu3;
import ca.uhn.fhir.validation.IValidatorModule; import ca.uhn.fhir.validation.IValidatorModule;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
@ -29,8 +28,6 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.EnableTransactionManagement;
import java.util.Map;
/* /*
* #%L * #%L
* HAPI FHIR JPA Server * HAPI FHIR JPA Server
@ -40,9 +37,9 @@ import java.util.Map;
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -55,6 +52,11 @@ import java.util.Map;
@EnableTransactionManagement @EnableTransactionManagement
public class BaseDstu3Config extends BaseConfig { public class BaseDstu3Config extends BaseConfig {
@Override
public FhirContext fhirContext() {
return fhirContextDstu3();
}
@Bean @Bean
@Primary @Primary
public FhirContext fhirContextDstu3() { public FhirContext fhirContextDstu3() {

View File

@ -16,7 +16,6 @@ import ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc;
import ca.uhn.fhir.jpa.term.IHapiTerminologySvcR4; import ca.uhn.fhir.jpa.term.IHapiTerminologySvcR4;
import ca.uhn.fhir.jpa.term.TerminologyLoaderSvcImpl; import ca.uhn.fhir.jpa.term.TerminologyLoaderSvcImpl;
import ca.uhn.fhir.jpa.util.ResourceCountCache; import ca.uhn.fhir.jpa.util.ResourceCountCache;
import ca.uhn.fhir.jpa.util.SingleItemLoadingCache;
import ca.uhn.fhir.jpa.validation.JpaValidationSupportChainR4; import ca.uhn.fhir.jpa.validation.JpaValidationSupportChainR4;
import ca.uhn.fhir.validation.IValidatorModule; import ca.uhn.fhir.validation.IValidatorModule;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
@ -32,8 +31,6 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.EnableTransactionManagement;
import java.util.Map;
/* /*
* #%L * #%L
* HAPI FHIR JPA Server * HAPI FHIR JPA Server
@ -58,6 +55,11 @@ import java.util.Map;
@EnableTransactionManagement @EnableTransactionManagement
public class BaseR4Config extends BaseConfig { public class BaseR4Config extends BaseConfig {
@Override
public FhirContext fhirContext() {
return fhirContextR4();
}
@Bean @Bean
@Primary @Primary
public FhirContext fhirContextR4() { public FhirContext fhirContextR4() {

View File

@ -78,6 +78,7 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice; import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl; import org.springframework.data.domain.SliceImpl;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate; import org.springframework.transaction.support.TransactionTemplate;
@ -98,6 +99,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import static org.apache.commons.lang3.StringUtils.*; import static org.apache.commons.lang3.StringUtils.*;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
@Repository
public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao { public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
public static final long INDEX_STATUS_INDEXED = 1L; public static final long INDEX_STATUS_INDEXED = 1L;

View File

@ -32,7 +32,7 @@ import java.util.Collection;
//@formatter:off //@formatter:off
@Entity @Entity
@Table(name = "HFJ_RES_VER", uniqueConstraints = { @Table(name = "HFJ_RES_VER", uniqueConstraints = {
@UniqueConstraint(name = "IDX_RESVER_ID_VER", columnNames = {"RES_ID", "RES_VER"}) @UniqueConstraint(name = ResourceHistoryTable.IDX_RESVER_ID_VER, columnNames = {"RES_ID", "RES_VER"})
}, indexes = { }, indexes = {
@Index(name = "IDX_RESVER_TYPE_DATE", columnList = "RES_TYPE,RES_UPDATED"), @Index(name = "IDX_RESVER_TYPE_DATE", columnList = "RES_TYPE,RES_UPDATED"),
@Index(name = "IDX_RESVER_ID_DATE", columnList = "RES_ID,RES_UPDATED"), @Index(name = "IDX_RESVER_ID_DATE", columnList = "RES_ID,RES_UPDATED"),
@ -42,6 +42,7 @@ import java.util.Collection;
public class ResourceHistoryTable extends BaseHasResource implements Serializable { public class ResourceHistoryTable extends BaseHasResource implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public static final String IDX_RESVER_ID_VER = "IDX_RESVER_ID_VER";
@Id @Id
@SequenceGenerator(name = "SEQ_RESOURCE_HISTORY_ID", sequenceName = "SEQ_RESOURCE_HISTORY_ID") @SequenceGenerator(name = "SEQ_RESOURCE_HISTORY_ID", sequenceName = "SEQ_RESOURCE_HISTORY_ID")

View File

@ -0,0 +1,30 @@
package ca.uhn.fhir.jpa.util;
import org.hibernate.dialect.DerbyTenSevenDialect;
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.SQLException;
public class DerbyTenSevenHapiFhirDialect extends DerbyTenSevenDialect {
private static final Logger ourLog = LoggerFactory.getLogger(DerbyTenSevenHapiFhirDialect.class);
@Override
public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
return new TemplatedViolatedConstraintNameExtracter() {
@Override
protected String doExtractConstraintName(SQLException theSqlException) throws NumberFormatException {
switch (theSqlException.getSQLState()) {
case "23505":
return this.extractUsingTemplate("unique or primary key constraint or unique index identified by '", "'", theSqlException.getMessage());
default:
return null;
}
}
};
}
}

View File

@ -45,11 +45,9 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName("PU_HapiFhirJpaDstu2"); retVal.setPersistenceUnitName("PU_HapiFhirJpaDstu2");
retVal.setDataSource(dataSource()); retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(jpaProperties()); retVal.setJpaProperties(jpaProperties());
return retVal; return retVal;
} }
@ -59,7 +57,7 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
extraProperties.put("hibernate.format_sql", "true"); extraProperties.put("hibernate.format_sql", "true");
extraProperties.put("hibernate.show_sql", "false"); extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update"); extraProperties.put("hibernate.hbm2ddl.auto", "update");
extraProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyTenSevenDialect"); extraProperties.put("hibernate.dialect", "ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect");
extraProperties.put("hibernate.search.model_mapping", LuceneSearchMappingFactory.class.getName()); extraProperties.put("hibernate.search.model_mapping", LuceneSearchMappingFactory.class.getName());
extraProperties.put("hibernate.search.default.directory_provider", "ram"); extraProperties.put("hibernate.search.default.directory_provider", "ram");
extraProperties.put("hibernate.search.lucene_version","LUCENE_CURRENT"); extraProperties.put("hibernate.search.lucene_version","LUCENE_CURRENT");

View File

@ -135,10 +135,9 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName("PU_HapiFhirJpaDstu3"); retVal.setPersistenceUnitName("PU_HapiFhirJpaDstu3");
retVal.setDataSource(dataSource()); retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider()); retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(jpaProperties()); retVal.setJpaProperties(jpaProperties());
return retVal; return retVal;
@ -150,7 +149,7 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 {
extraProperties.put("hibernate.format_sql", "false"); extraProperties.put("hibernate.format_sql", "false");
extraProperties.put("hibernate.show_sql", "false"); extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update"); extraProperties.put("hibernate.hbm2ddl.auto", "update");
extraProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyTenSevenDialect"); extraProperties.put("hibernate.dialect", "ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect");
extraProperties.put("hibernate.search.model_mapping", LuceneSearchMappingFactory.class.getName()); extraProperties.put("hibernate.search.model_mapping", LuceneSearchMappingFactory.class.getName());
extraProperties.put("hibernate.search.default.directory_provider", "ram"); extraProperties.put("hibernate.search.default.directory_provider", "ram");
extraProperties.put("hibernate.search.lucene_version", "LUCENE_CURRENT"); extraProperties.put("hibernate.search.lucene_version", "LUCENE_CURRENT");

View File

@ -27,11 +27,7 @@ public class TestDstu3WithoutLuceneConfig extends TestDstu3Config {
@Override @Override
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName("PU_HapiFhirJpaDstu3");
retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(jpaProperties()); retVal.setJpaProperties(jpaProperties());
return retVal; return retVal;
} }
@ -41,7 +37,7 @@ public class TestDstu3WithoutLuceneConfig extends TestDstu3Config {
extraProperties.put("hibernate.format_sql", "false"); extraProperties.put("hibernate.format_sql", "false");
extraProperties.put("hibernate.show_sql", "false"); extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update"); extraProperties.put("hibernate.hbm2ddl.auto", "update");
extraProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyTenSevenDialect"); extraProperties.put("hibernate.dialect", "ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect");
extraProperties.put("hibernate.search.autoregister_listeners", "false"); extraProperties.put("hibernate.search.autoregister_listeners", "false");
return extraProperties; return extraProperties;
} }

View File

@ -12,8 +12,10 @@ import org.hibernate.query.criteria.LiteralHandlingMode;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.orm.hibernate5.HibernateExceptionTranslator;
import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaDialect;
import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
@ -115,11 +117,9 @@ public class TestR4Config extends BaseJavaConfigR4 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName("PU_HapiFhirJpaR4"); retVal.setPersistenceUnitName("PU_HapiFhirJpaR4");
retVal.setDataSource(dataSource()); retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(jpaProperties()); retVal.setJpaProperties(jpaProperties());
return retVal; return retVal;
} }
@ -130,7 +130,7 @@ public class TestR4Config extends BaseJavaConfigR4 {
extraProperties.put("hibernate.format_sql", "false"); extraProperties.put("hibernate.format_sql", "false");
extraProperties.put("hibernate.show_sql", "false"); extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update"); extraProperties.put("hibernate.hbm2ddl.auto", "update");
extraProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyTenSevenDialect"); extraProperties.put("hibernate.dialect", "ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect");
extraProperties.put("hibernate.search.model_mapping", ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory.class.getName()); extraProperties.put("hibernate.search.model_mapping", ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory.class.getName());
extraProperties.put("hibernate.search.default.directory_provider", "ram"); extraProperties.put("hibernate.search.default.directory_provider", "ram");
extraProperties.put("hibernate.search.lucene_version", "LUCENE_CURRENT"); extraProperties.put("hibernate.search.lucene_version", "LUCENE_CURRENT");

View File

@ -27,11 +27,8 @@ public class TestR4WithoutLuceneConfig extends TestR4Config {
@Override @Override
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName("PU_HapiFhirJpaR4");
retVal.setDataSource(dataSource()); retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(jpaProperties()); retVal.setJpaProperties(jpaProperties());
return retVal; return retVal;
} }
@ -41,7 +38,7 @@ public class TestR4WithoutLuceneConfig extends TestR4Config {
extraProperties.put("hibernate.format_sql", "false"); extraProperties.put("hibernate.format_sql", "false");
extraProperties.put("hibernate.show_sql", "false"); extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update"); extraProperties.put("hibernate.hbm2ddl.auto", "update");
extraProperties.put("hibernate.dialect", "org.hibernate.dialect.DerbyTenSevenDialect"); extraProperties.put("hibernate.dialect", "ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect");
extraProperties.put("hibernate.search.autoregister_listeners", "false"); extraProperties.put("hibernate.search.autoregister_listeners", "false");
return extraProperties; return extraProperties;
} }

View File

@ -1,27 +1,41 @@
package ca.uhn.fhir.jpa.dao.r4; package ca.uhn.fhir.jpa.dao.r4;
import static org.apache.commons.lang3.StringUtils.defaultString; import ca.uhn.fhir.jpa.dao.*;
import static org.hamcrest.Matchers.*; import ca.uhn.fhir.jpa.entity.ResourceEncodingEnum;
import static org.junit.Assert.*; import ca.uhn.fhir.jpa.entity.ResourceHistoryTable;
import static org.mockito.Matchers.eq; import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
import static org.mockito.Mockito.*; import ca.uhn.fhir.jpa.entity.TagTypeEnum;
import ca.uhn.fhir.model.api.Include;
import java.io.IOException; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import java.util.*; import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.server.exceptions.*;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.util.TestUtil;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.hamcrest.core.StringContains; import org.hamcrest.core.StringContains;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.*; import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.Bundle.*; import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r4.model.Bundle.BundleType;
import org.hl7.fhir.r4.model.Bundle.HTTPVerb;
import org.hl7.fhir.r4.model.Enumerations.AdministrativeGender; import org.hl7.fhir.r4.model.Enumerations.AdministrativeGender;
import org.hl7.fhir.r4.model.Enumerations.PublicationStatus; import org.hl7.fhir.r4.model.Enumerations.PublicationStatus;
import org.hl7.fhir.r4.model.Observation.ObservationStatus; import org.hl7.fhir.r4.model.Observation.ObservationStatus;
import org.hl7.fhir.r4.model.OperationOutcome.IssueSeverity; import org.hl7.fhir.r4.model.OperationOutcome.IssueSeverity;
import org.hl7.fhir.r4.model.OperationOutcome.IssueType; import org.hl7.fhir.r4.model.OperationOutcome.IssueType;
import org.hl7.fhir.r4.model.Quantity.QuantityComparator; import org.hl7.fhir.r4.model.Quantity.QuantityComparator;
import org.hl7.fhir.instance.model.api.*;
import org.junit.*; import org.junit.*;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionDefinition;
@ -29,24 +43,21 @@ import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate; import org.springframework.transaction.support.TransactionTemplate;
import com.google.common.base.Charsets; import java.io.IOException;
import com.google.common.collect.Lists; import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import ca.uhn.fhir.jpa.dao.*; import static org.apache.commons.lang3.StringUtils.defaultString;
import ca.uhn.fhir.jpa.entity.*; import static org.hamcrest.Matchers.contains;
import ca.uhn.fhir.model.api.Include; import static org.hamcrest.Matchers.*;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import static org.junit.Assert.*;
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum; import static org.mockito.Matchers.eq;
import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum; import static org.mockito.Mockito.*;
import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.server.exceptions.*;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.util.TestUtil;
@SuppressWarnings({ "unchecked", "deprecation" }) @SuppressWarnings({"unchecked", "deprecation"})
public class FhirResourceDaoR4Test extends BaseJpaR4Test { public class FhirResourceDaoR4Test extends BaseJpaR4Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoR4Test.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoR4Test.class);
@ -82,47 +93,6 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
} }
} }
@Test
public void testSaveAndReturnCollectionBundle() throws IOException {
String input = IOUtils.toString(FhirResourceDaoR4Test.class.getResourceAsStream("/r4/collection-bundle.json"));
Bundle inputBundle = myFhirCtx.newJsonParser().parseResource(Bundle.class, input);
myBundleDao.update(inputBundle);
Bundle outputBundle = myBundleDao.read(new IdType("cftest"));
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(outputBundle));
for (BundleEntryComponent next : outputBundle.getEntry()) {
assertTrue(next.getResource().getIdElement().hasIdPart());
}
}
/**
* See #773
*/
@Test
public void testDeleteResourceWithOutboundDeletedResources() {
myDaoConfig.setEnforceReferentialIntegrityOnDelete(false);
Organization org = new Organization();
org.setId("ORG");
org.setName("ORG");
myOrganizationDao.update(org);
Patient pat = new Patient();
pat.setId("PAT");
pat.setActive(true);
pat.setManagingOrganization(new Reference("Organization/ORG"));
myPatientDao.update(pat);
myOrganizationDao.delete(new IdType("Organization/ORG"));
myPatientDao.delete(new IdType("Patient/PAT"));
}
@Before @Before
public void beforeDisableResultReuse() { public void beforeDisableResultReuse() {
myDaoConfig.setReuseCachedSearchResultsForMillis(null); myDaoConfig.setReuseCachedSearchResultsForMillis(null);
@ -161,7 +131,6 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
} }
} }
private void sortCodings(List<Coding> theSecLabels) { private void sortCodings(List<Coding> theSecLabels) {
Collections.sort(theSecLabels, new Comparator<Coding>() { Collections.sort(theSecLabels, new Comparator<Coding>() {
@Override @Override
@ -170,7 +139,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
} }
}); });
} }
private List<CanonicalType> sortIds(List<CanonicalType> theProfiles) { private List<CanonicalType> sortIds(List<CanonicalType> theProfiles) {
ArrayList<CanonicalType> retVal = new ArrayList<>(theProfiles); ArrayList<CanonicalType> retVal = new ArrayList<>(theProfiles);
Collections.sort(retVal, new Comparator<UriType>() { Collections.sort(retVal, new Comparator<UriType>() {
@ -181,7 +150,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
}); });
return retVal; return retVal;
} }
@Test @Test
public void testCantSearchForDeletedResourceByLanguageOrTag() { public void testCantSearchForDeletedResourceByLanguageOrTag() {
String methodName = "testCantSearchForDeletedResourceByLanguageOrTag"; String methodName = "testCantSearchForDeletedResourceByLanguageOrTag";
@ -453,6 +422,54 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
assertGone(id.toUnqualifiedVersionless()); assertGone(id.toUnqualifiedVersionless());
} }
@Test
public void testConflictingUpdates() throws ExecutionException, InterruptedException {
ExecutorService pool = Executors.newFixedThreadPool(5);
try {
Patient p = new Patient();
p.setActive(true);
IIdType id = myPatientDao.create(p).getId();
List<Future<String>> futures = new ArrayList<>();
for (int i = 0; i < 50; i++) {
Patient updatePatient = new Patient();
updatePatient.setId(id.toUnqualifiedVersionless());
updatePatient.addIdentifier().setSystem("" + i);
updatePatient.setActive(true);
int finalI = i;
Future<String> future = pool.submit(() -> {
ourLog.info("Starting update {}", finalI);
try {
try {
myPatientDao.update(updatePatient);
} catch (PreconditionFailedException e) {
assertEquals("The operation has failed with a version constraint failure. This generally means that two clients/threads were trying to update the same resource at the same time, and this request was chosen as the failing request.", e.getMessage());
}
} catch (Exception e) {
ourLog.error("Failure", e);
return e.toString();
}
ourLog.info("Finished update {}", finalI);
return null;
});
futures.add(future);
}
for (Future<String> next : futures) {
String nextError = next.get();
if (StringUtils.isNotBlank(nextError)) {
fail(nextError);
}
}
} finally {
pool.shutdown();
}
}
@Test @Test
@Ignore @Ignore
public void testCreateBuiltInProfiles() throws Exception { public void testCreateBuiltInProfiles() throws Exception {
@ -522,8 +539,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
myBundleDao.create(bundle, mySrd); myBundleDao.create(bundle, mySrd);
} }
@Test @Test
public void testCreateDifferentTypesWithSameForcedId() { public void testCreateDifferentTypesWithSameForcedId() {
String idName = "forcedId"; String idName = "forcedId";
@ -544,12 +560,11 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
obs = myObservationDao.read(obsId.toUnqualifiedVersionless(), mySrd); obs = myObservationDao.read(obsId.toUnqualifiedVersionless(), mySrd);
} }
@Test @Test
public void testCreateDuplicateTagsDoesNotCauseDuplicates() { public void testCreateDuplicateTagsDoesNotCauseDuplicates() {
Patient p = new Patient(); Patient p = new Patient();
p.setActive(true); p.setActive(true);
p.getMeta().addTag().setSystem("FOO").setCode("BAR"); p.getMeta().addTag().setSystem("FOO").setCode("BAR");
p.getMeta().addTag().setSystem("FOO").setCode("BAR"); p.getMeta().addTag().setSystem("FOO").setCode("BAR");
p.getMeta().addTag().setSystem("FOO").setCode("BAR"); p.getMeta().addTag().setSystem("FOO").setCode("BAR");
@ -557,9 +572,9 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
p.getMeta().addTag().setSystem("FOO").setCode("BAR"); p.getMeta().addTag().setSystem("FOO").setCode("BAR");
p.getMeta().addTag().setSystem("FOO").setCode("BAR"); p.getMeta().addTag().setSystem("FOO").setCode("BAR");
p.getMeta().addTag().setSystem("FOO").setCode("BAR"); p.getMeta().addTag().setSystem("FOO").setCode("BAR");
myPatientDao.create(p); myPatientDao.create(p);
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() { new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
@Override @Override
protected void doInTransactionWithoutResult(TransactionStatus theStatus) { protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
@ -567,24 +582,24 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
assertThat(myTagDefinitionDao.findAll(), hasSize(1)); assertThat(myTagDefinitionDao.findAll(), hasSize(1));
} }
}); });
} }
@Test @Test
public void testCreateEmptyTagsIsIgnored() { public void testCreateEmptyTagsIsIgnored() {
Patient p = new Patient(); Patient p = new Patient();
p.setActive(true); p.setActive(true);
// Add an empty tag // Add an empty tag
p.getMeta().addTag(); p.getMeta().addTag();
// Add another empty tag // Add another empty tag
p.getMeta().addTag().setSystem(""); p.getMeta().addTag().setSystem("");
p.getMeta().addTag().setCode(""); p.getMeta().addTag().setCode("");
p.getMeta().addTag().setDisplay(""); p.getMeta().addTag().setDisplay("");
myPatientDao.create(p); myPatientDao.create(p);
new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() { new TransactionTemplate(myTxManager).execute(new TransactionCallbackWithoutResult() {
@Override @Override
protected void doInTransactionWithoutResult(TransactionStatus theStatus) { protected void doInTransactionWithoutResult(TransactionStatus theStatus) {
@ -592,29 +607,29 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
assertThat(myTagDefinitionDao.findAll(), empty()); assertThat(myTagDefinitionDao.findAll(), empty());
} }
}); });
} }
@Test @Test
public void testCreateLongString() { public void testCreateLongString() {
//@formatter:off //@formatter:off
String input = "<NamingSystem>\n" + String input = "<NamingSystem>\n" +
" <name value=\"NDF-RT (National Drug File Reference Terminology)\"/>\n" + " <name value=\"NDF-RT (National Drug File Reference Terminology)\"/>\n" +
" <status value=\"draft\"/>\n" + " <status value=\"draft\"/>\n" +
" <kind value=\"codesystem\"/>\n" + " <kind value=\"codesystem\"/>\n" +
" <publisher value=\"HL7, Inc\"/>\n" + " <publisher value=\"HL7, Inc\"/>\n" +
" <date value=\"2015-08-21\"/>\n" + " <date value=\"2015-08-21\"/>\n" +
" <uniqueId>\n" + " <uniqueId>\n" +
" <type value=\"uri\"/>\n" + " <type value=\"uri\"/>\n" +
" <value value=\"http://hl7.org/fhir/ndfrt\"/>\n" + " <value value=\"http://hl7.org/fhir/ndfrt\"/>\n" +
" <preferred value=\"true\"/>\n" + " <preferred value=\"true\"/>\n" +
" </uniqueId>\n" + " </uniqueId>\n" +
" <uniqueId>\n" + " <uniqueId>\n" +
" <type value=\"oid\"/>\n" + " <type value=\"oid\"/>\n" +
" <value value=\"2.16.840.1.113883.6.209\"/>\n" + " <value value=\"2.16.840.1.113883.6.209\"/>\n" +
" <preferred value=\"false\"/>\n" + " <preferred value=\"false\"/>\n" +
" </uniqueId>\n" + " </uniqueId>\n" +
" </NamingSystem>"; " </NamingSystem>";
//@formatter:on //@formatter:on
NamingSystem res = myFhirCtx.newXmlParser().parseResource(NamingSystem.class, input); NamingSystem res = myFhirCtx.newXmlParser().parseResource(NamingSystem.class, input);
@ -677,9 +692,9 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
Organization org = new Organization(); Organization org = new Organization();
org.setActive(true); org.setActive(true);
IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless(); IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless();
myOrganizationDao.delete(orgId); myOrganizationDao.delete(orgId);
Patient p = new Patient(); Patient p = new Patient();
p.getManagingOrganization().setReferenceElement(orgId); p.getManagingOrganization().setReferenceElement(orgId);
try { try {
@ -853,7 +868,6 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
} }
} }
@Test @Test
public void testCreateWithInvalidReferenceFailsGracefully() { public void testCreateWithInvalidReferenceFailsGracefully() {
Patient patient = new Patient(); Patient patient = new Patient();
@ -1108,49 +1122,6 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
} }
@Test
public void testDeleteTwicePerformsNoOp() {
Patient patient = new Patient();
patient.setActive(true);
IIdType id = myPatientDao.create(patient, mySrd).getId();
assertNotNull(id.getIdPartAsLong());
assertEquals("1", id.getVersionIdPart());
IIdType id2 = myPatientDao.delete(id.toUnqualifiedVersionless()).getId();
assertEquals(id.getIdPart(), id2.getIdPart());
assertEquals("2", id2.getVersionIdPart());
IIdType id3 = myPatientDao.delete(id.toUnqualifiedVersionless()).getId();
assertEquals(id.getIdPart(), id3.getIdPart());
assertEquals("2", id3.getVersionIdPart());
IIdType id4 = myPatientDao.delete(id.toUnqualifiedVersionless()).getId();
assertEquals(id.getIdPart(), id4.getIdPart());
assertEquals("2", id4.getVersionIdPart());
patient = new Patient();
patient.setId(id.getIdPart());
patient.setActive(false);
IIdType id5 = myPatientDao.update(patient).getId();
assertEquals(id.getIdPart(), id5.getIdPart());
assertEquals("3", id5.getVersionIdPart());
patient = myPatientDao.read(id.withVersion("1"));
assertEquals(true, patient.getActive());
try {
myPatientDao.read(id.withVersion("2"));
fail();
} catch (ResourceGoneException e) {
// good
}
patient = myPatientDao.read(id.withVersion("3"));
assertEquals(false, patient.getActive());
}
@Test @Test
public void testDeleteResource() { public void testDeleteResource() {
int initialHistory = myPatientDao.history(null, null, mySrd).size(); int initialHistory = myPatientDao.history(null, null, mySrd).size();
@ -1215,6 +1186,29 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
} }
/**
* See #773
*/
@Test
public void testDeleteResourceWithOutboundDeletedResources() {
myDaoConfig.setEnforceReferentialIntegrityOnDelete(false);
Organization org = new Organization();
org.setId("ORG");
org.setName("ORG");
myOrganizationDao.update(org);
Patient pat = new Patient();
pat.setId("PAT");
pat.setActive(true);
pat.setManagingOrganization(new Reference("Organization/ORG"));
myPatientDao.update(pat);
myOrganizationDao.delete(new IdType("Organization/ORG"));
myPatientDao.delete(new IdType("Patient/PAT"));
}
@Test @Test
public void testDeleteThenUndelete() { public void testDeleteThenUndelete() {
Patient patient = new Patient(); Patient patient = new Patient();
@ -1248,6 +1242,49 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
assertEquals(id2, gotId); assertEquals(id2, gotId);
} }
@Test
public void testDeleteTwicePerformsNoOp() {
Patient patient = new Patient();
patient.setActive(true);
IIdType id = myPatientDao.create(patient, mySrd).getId();
assertNotNull(id.getIdPartAsLong());
assertEquals("1", id.getVersionIdPart());
IIdType id2 = myPatientDao.delete(id.toUnqualifiedVersionless()).getId();
assertEquals(id.getIdPart(), id2.getIdPart());
assertEquals("2", id2.getVersionIdPart());
IIdType id3 = myPatientDao.delete(id.toUnqualifiedVersionless()).getId();
assertEquals(id.getIdPart(), id3.getIdPart());
assertEquals("2", id3.getVersionIdPart());
IIdType id4 = myPatientDao.delete(id.toUnqualifiedVersionless()).getId();
assertEquals(id.getIdPart(), id4.getIdPart());
assertEquals("2", id4.getVersionIdPart());
patient = new Patient();
patient.setId(id.getIdPart());
patient.setActive(false);
IIdType id5 = myPatientDao.update(patient).getId();
assertEquals(id.getIdPart(), id5.getIdPart());
assertEquals("3", id5.getVersionIdPart());
patient = myPatientDao.read(id.withVersion("1"));
assertEquals(true, patient.getActive());
try {
myPatientDao.read(id.withVersion("2"));
fail();
} catch (ResourceGoneException e) {
// good
}
patient = myPatientDao.read(id.withVersion("3"));
assertEquals(false, patient.getActive());
}
@Test @Test
public void testDeleteWithHas() { public void testDeleteWithHas() {
Observation obs1 = new Observation(); Observation obs1 = new Observation();
@ -1784,7 +1821,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
preDates.add(new Date()); preDates.add(new Date());
Thread.sleep(100); Thread.sleep(100);
patient.setId(id); patient.setId(id);
patient.getName().get(0).getFamilyElement().setValue(methodName + "_i"+i); patient.getName().get(0).getFamilyElement().setValue(methodName + "_i" + i);
ids.add(myPatientDao.update(patient, mySrd).getId().toUnqualified().getValue()); ids.add(myPatientDao.update(patient, mySrd).getId().toUnqualified().getValue());
} }
@ -2143,27 +2180,27 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
public void testOrganizationName() { public void testOrganizationName() {
//@formatter:off //@formatter:off
String inputStr = String inputStr =
"{" + "{" +
" \"resourceType\":\"Organization\",\n" + " \"resourceType\":\"Organization\",\n" +
" \"extension\":[\n" + " \"extension\":[\n" +
" {\n" + " {\n" +
" \"url\":\"http://fhir.connectinggta.ca/Profile/organization#providerIdPool\",\n" + " \"url\":\"http://fhir.connectinggta.ca/Profile/organization#providerIdPool\",\n" +
" \"valueUri\":\"urn:oid:2.16.840.1.113883.3.239.23.21.1\"\n" + " \"valueUri\":\"urn:oid:2.16.840.1.113883.3.239.23.21.1\"\n" +
" }\n" + " }\n" +
" ],\n" + " ],\n" +
" \"text\":{\n" + " \"text\":{\n" +
" \"status\":\"empty\",\n" + " \"status\":\"empty\",\n" +
" \"div\":\"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">No narrative template available for resource profile: http://fhir.connectinggta.ca/Profile/organization</div>\"\n" + " \"div\":\"<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">No narrative template available for resource profile: http://fhir.connectinggta.ca/Profile/organization</div>\"\n" +
" },\n" + " },\n" +
" \"identifier\":[\n" + " \"identifier\":[\n" +
" {\n" + " {\n" +
" \"use\":\"official\",\n" + " \"use\":\"official\",\n" +
" \"system\":\"urn:cgta:hsp_ids\",\n" + " \"system\":\"urn:cgta:hsp_ids\",\n" +
" \"value\":\"urn:oid:2.16.840.1.113883.3.239.23.21\"\n" + " \"value\":\"urn:oid:2.16.840.1.113883.3.239.23.21\"\n" +
" }\n" + " }\n" +
" ],\n" + " ],\n" +
" \"name\":\"Peterborough Regional Health Centre\"\n" + " \"name\":\"Peterborough Regional Health Centre\"\n" +
"}\n"; "}\n";
//@formatter:on //@formatter:on
@ -2602,7 +2639,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
final Patient p = new Patient(); final Patient p = new Patient();
p.setGender(AdministrativeGender.MALE); p.setGender(AdministrativeGender.MALE);
final IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless(); final IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless();
TransactionTemplate tx = new TransactionTemplate(myTxManager); TransactionTemplate tx = new TransactionTemplate(myTxManager);
tx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); tx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
tx.execute(new TransactionCallbackWithoutResult() { tx.execute(new TransactionCallbackWithoutResult() {
@ -2616,7 +2653,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
myResourceHistoryTableDao.save(table); myResourceHistoryTableDao.save(table);
} }
}); });
Patient read = myPatientDao.read(id); Patient read = myPatientDao.read(id);
String string = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(read); String string = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(read);
ourLog.info(string); ourLog.info(string);
@ -2851,6 +2888,21 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
assertEquals(BundleEntrySearchModeEnum.INCLUDE.getCode(), ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.get((IAnyResource) results.get(1))); assertEquals(BundleEntrySearchModeEnum.INCLUDE.getCode(), ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.get((IAnyResource) results.get(1)));
} }
@Test
public void testSaveAndReturnCollectionBundle() throws IOException {
String input = IOUtils.toString(FhirResourceDaoR4Test.class.getResourceAsStream("/r4/collection-bundle.json"));
Bundle inputBundle = myFhirCtx.newJsonParser().parseResource(Bundle.class, input);
myBundleDao.update(inputBundle);
Bundle outputBundle = myBundleDao.read(new IdType("cftest"));
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(outputBundle));
for (BundleEntryComponent next : outputBundle.getEntry()) {
assertTrue(next.getResource().getIdElement().hasIdPart());
}
}
@Test() @Test()
public void testSortByComposite() { public void testSortByComposite() {
Observation o = new Observation(); Observation o = new Observation();
@ -2920,6 +2972,40 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
} }
@Test
@Ignore
public void testSortByEncounterLength() {
String methodName = "testSortByNumber";
Encounter e1 = new Encounter();
e1.addIdentifier().setSystem("foo").setValue(methodName);
e1.getLength().setSystem(BaseHapiFhirDao.UCUM_NS).setCode("min").setValue(4.0 * 24 * 60);
IIdType id1 = myEncounterDao.create(e1, mySrd).getId().toUnqualifiedVersionless();
Encounter e3 = new Encounter();
e3.addIdentifier().setSystem("foo").setValue(methodName);
e3.getLength().setSystem(BaseHapiFhirDao.UCUM_NS).setCode("year").setValue(3.0);
IIdType id3 = myEncounterDao.create(e3, mySrd).getId().toUnqualifiedVersionless();
Encounter e2 = new Encounter();
e2.addIdentifier().setSystem("foo").setValue(methodName);
e2.getLength().setSystem(BaseHapiFhirDao.UCUM_NS).setCode("year").setValue(2.0);
IIdType id2 = myEncounterDao.create(e2, mySrd).getId().toUnqualifiedVersionless();
SearchParameterMap pm;
List<String> actual;
pm = new SearchParameterMap();
pm.setSort(new SortSpec(Encounter.SP_LENGTH));
actual = toUnqualifiedVersionlessIdValues(myEncounterDao.search(pm));
assertThat(actual, contains(toValues(id1, id2, id3)));
pm = new SearchParameterMap();
pm.setSort(new SortSpec(Encounter.SP_LENGTH, SortOrderEnum.DESC));
actual = toUnqualifiedVersionlessIdValues(myEncounterDao.search(pm));
assertThat(actual, contains(toValues(id3, id2, id1)));
}
@Test @Test
public void testSortById() { public void testSortById() {
String methodName = "testSortBTyId"; String methodName = "testSortBTyId";
@ -3053,41 +3139,6 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
assertThat(actual, contains(toValues(id3, id2, id1))); assertThat(actual, contains(toValues(id3, id2, id1)));
} }
@Test
@Ignore
public void testSortByEncounterLength() {
String methodName = "testSortByNumber";
Encounter e1 = new Encounter();
e1.addIdentifier().setSystem("foo").setValue(methodName);
e1.getLength().setSystem(BaseHapiFhirDao.UCUM_NS).setCode("min").setValue(4.0 * 24 * 60);
IIdType id1 = myEncounterDao.create(e1, mySrd).getId().toUnqualifiedVersionless();
Encounter e3 = new Encounter();
e3.addIdentifier().setSystem("foo").setValue(methodName);
e3.getLength().setSystem(BaseHapiFhirDao.UCUM_NS).setCode("year").setValue(3.0);
IIdType id3 = myEncounterDao.create(e3, mySrd).getId().toUnqualifiedVersionless();
Encounter e2 = new Encounter();
e2.addIdentifier().setSystem("foo").setValue(methodName);
e2.getLength().setSystem(BaseHapiFhirDao.UCUM_NS).setCode("year").setValue(2.0);
IIdType id2 = myEncounterDao.create(e2, mySrd).getId().toUnqualifiedVersionless();
SearchParameterMap pm;
List<String> actual;
pm = new SearchParameterMap();
pm.setSort(new SortSpec(Encounter.SP_LENGTH));
actual = toUnqualifiedVersionlessIdValues(myEncounterDao.search(pm));
assertThat(actual, contains(toValues(id1, id2, id3)));
pm = new SearchParameterMap();
pm.setSort(new SortSpec(Encounter.SP_LENGTH, SortOrderEnum.DESC));
actual = toUnqualifiedVersionlessIdValues(myEncounterDao.search(pm));
assertThat(actual, contains(toValues(id3, id2, id1)));
}
public void testSortByQuantity() { public void testSortByQuantity() {
Observation res; Observation res;
@ -3694,7 +3745,7 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
public static void assertConflictException(ResourceVersionConflictException e) { public static void assertConflictException(ResourceVersionConflictException e) {
assertThat(e.getMessage(), matchesPattern( assertThat(e.getMessage(), matchesPattern(
"Unable to delete [a-zA-Z]+/[0-9]+ because at least one resource has a reference to this resource. First reference found was resource [a-zA-Z]+/[0-9]+ in path [a-zA-Z]+.[a-zA-Z]+")); "Unable to delete [a-zA-Z]+/[0-9]+ because at least one resource has a reference to this resource. First reference found was resource [a-zA-Z]+/[0-9]+ in path [a-zA-Z]+.[a-zA-Z]+"));
} }
private static List<String> toStringList(List<CanonicalType> theUriType) { private static List<String> toStringList(List<CanonicalType> theUriType) {

View File

@ -6,6 +6,7 @@ import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource; import javax.sql.DataSource;
import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory; import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory;
import ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect;
import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
import org.hibernate.jpa.HibernatePersistenceProvider; import org.hibernate.jpa.HibernatePersistenceProvider;
@ -58,18 +59,16 @@ public class FhirServerConfig extends BaseJavaConfigDstu3 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName("HAPI_PU"); retVal.setPersistenceUnitName("HAPI_PU");
retVal.setDataSource(dataSource()); retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(jpaProperties()); retVal.setJpaProperties(jpaProperties());
return retVal; return retVal;
} }
private Properties jpaProperties() { private Properties jpaProperties() {
Properties extraProperties = new Properties(); Properties extraProperties = new Properties();
extraProperties.put("hibernate.dialect", org.hibernate.dialect.DerbyTenSevenDialect.class.getName()); extraProperties.put("hibernate.dialect", DerbyTenSevenHapiFhirDialect.class.getName());
extraProperties.put("hibernate.format_sql", "true"); extraProperties.put("hibernate.format_sql", "true");
extraProperties.put("hibernate.show_sql", "false"); extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update"); extraProperties.put("hibernate.hbm2ddl.auto", "update");

View File

@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.demo;
import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu2; import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu2;
import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory; import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory;
import ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect;
import ca.uhn.fhir.jpa.util.SubscriptionsRequireManualActivationInterceptorDstu2; import ca.uhn.fhir.jpa.util.SubscriptionsRequireManualActivationInterceptorDstu2;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor; import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor;
@ -59,18 +60,16 @@ public class FhirServerConfigDstu2 extends BaseJavaConfigDstu2 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName("HAPI_PU"); retVal.setPersistenceUnitName("HAPI_PU");
retVal.setDataSource(dataSource()); retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(jpaProperties()); retVal.setJpaProperties(jpaProperties());
return retVal; return retVal;
} }
private Properties jpaProperties() { private Properties jpaProperties() {
Properties extraProperties = new Properties(); Properties extraProperties = new Properties();
extraProperties.put("hibernate.dialect", org.hibernate.dialect.DerbyTenSevenDialect.class.getName()); extraProperties.put("hibernate.dialect", DerbyTenSevenHapiFhirDialect.class.getName());
extraProperties.put("hibernate.format_sql", "true"); extraProperties.put("hibernate.format_sql", "true");
extraProperties.put("hibernate.show_sql", "false"); extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update"); extraProperties.put("hibernate.hbm2ddl.auto", "update");

View File

@ -55,18 +55,16 @@ public class FhirServerConfig extends BaseJavaConfigDstu3 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName("HAPI_PU"); retVal.setPersistenceUnitName("HAPI_PU");
retVal.setDataSource(dataSource()); retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(jpaProperties()); retVal.setJpaProperties(jpaProperties());
return retVal; return retVal;
} }
private Properties jpaProperties() { private Properties jpaProperties() {
Properties extraProperties = new Properties(); Properties extraProperties = new Properties();
extraProperties.put("hibernate.dialect", org.hibernate.dialect.DerbyTenSevenDialect.class.getName()); extraProperties.put("hibernate.dialect", ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect.class.getName());
extraProperties.put("hibernate.format_sql", "true"); extraProperties.put("hibernate.format_sql", "true");
extraProperties.put("hibernate.show_sql", "false"); extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update"); extraProperties.put("hibernate.hbm2ddl.auto", "update");

View File

@ -3,6 +3,7 @@ package ca.uhn.fhirtest.config;
import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu2; import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu2;
import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory; import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory;
import ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect;
import ca.uhn.fhir.jpa.util.SubscriptionsRequireManualActivationInterceptorDstu2; import ca.uhn.fhir.jpa.util.SubscriptionsRequireManualActivationInterceptorDstu2;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
@ -12,7 +13,6 @@ import ca.uhn.fhir.validation.ResultSeverityEnum;
import ca.uhn.fhirtest.interceptor.TdlSecurityInterceptor; import ca.uhn.fhirtest.interceptor.TdlSecurityInterceptor;
import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
import org.hibernate.dialect.DerbyTenSevenDialect;
import org.hibernate.jpa.HibernatePersistenceProvider; import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
@ -92,7 +92,7 @@ public class TdlDstu2Config extends BaseJavaConfigDstu2 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName("PU_HapiFhirJpaDstu2"); retVal.setPersistenceUnitName("PU_HapiFhirJpaDstu2");
retVal.setDataSource(dataSource()); retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity"); retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
@ -103,7 +103,7 @@ public class TdlDstu2Config extends BaseJavaConfigDstu2 {
private Properties jpaProperties() { private Properties jpaProperties() {
Properties extraProperties = new Properties(); Properties extraProperties = new Properties();
extraProperties.put("hibernate.dialect", DerbyTenSevenDialect.class.getName()); extraProperties.put("hibernate.dialect", DerbyTenSevenHapiFhirDialect.class.getName());
extraProperties.put("hibernate.format_sql", "false"); extraProperties.put("hibernate.format_sql", "false");
extraProperties.put("hibernate.show_sql", "false"); extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update"); extraProperties.put("hibernate.hbm2ddl.auto", "update");

View File

@ -1,14 +1,18 @@
package ca.uhn.fhirtest.config; package ca.uhn.fhirtest.config;
import java.util.Properties; import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu3;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory; import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory;
import ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect;
import ca.uhn.fhir.jpa.util.SubscriptionsRequireManualActivationInterceptorDstu3;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
import ca.uhn.fhir.rest.server.interceptor.ResponseValidatingInterceptor;
import ca.uhn.fhir.validation.ResultSeverityEnum;
import ca.uhn.fhirtest.interceptor.TdlSecurityInterceptor;
import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
import org.hibernate.dialect.DerbyTenSevenDialect;
import org.hibernate.jpa.HibernatePersistenceProvider; import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
@ -21,15 +25,9 @@ import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.EnableTransactionManagement;
import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu3; import javax.persistence.EntityManagerFactory;
import ca.uhn.fhir.jpa.dao.DaoConfig; import javax.sql.DataSource;
import ca.uhn.fhir.jpa.util.SubscriptionsRequireManualActivationInterceptorDstu3; import java.util.Properties;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
import ca.uhn.fhir.rest.server.interceptor.ResponseValidatingInterceptor;
import ca.uhn.fhir.validation.ResultSeverityEnum;
import ca.uhn.fhirtest.interceptor.TdlSecurityInterceptor;
@Configuration @Configuration
@Import(CommonConfig.class) @Import(CommonConfig.class)
@ -74,18 +72,16 @@ public class TdlDstu3Config extends BaseJavaConfigDstu3 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName("PU_HapiFhirJpaDstu3"); retVal.setPersistenceUnitName("PU_HapiFhirJpaDstu3");
retVal.setDataSource(dataSource()); retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(jpaProperties()); retVal.setJpaProperties(jpaProperties());
return retVal; return retVal;
} }
private Properties jpaProperties() { private Properties jpaProperties() {
Properties extraProperties = new Properties(); Properties extraProperties = new Properties();
extraProperties.put("hibernate.dialect", DerbyTenSevenDialect.class.getName()); extraProperties.put("hibernate.dialect", DerbyTenSevenHapiFhirDialect.class.getName());
extraProperties.put("hibernate.format_sql", "false"); extraProperties.put("hibernate.format_sql", "false");
extraProperties.put("hibernate.show_sql", "false"); extraProperties.put("hibernate.show_sql", "false");
extraProperties.put("hibernate.hbm2ddl.auto", "update"); extraProperties.put("hibernate.hbm2ddl.auto", "update");

View File

@ -3,15 +3,14 @@ package ca.uhn.fhirtest.config;
import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu2; import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu2;
import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory; import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory;
import ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor; import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
import ca.uhn.fhir.validation.ResultSeverityEnum; import ca.uhn.fhir.validation.ResultSeverityEnum;
import ca.uhn.fhirtest.interceptor.PublicSecurityInterceptor; import ca.uhn.fhirtest.interceptor.PublicSecurityInterceptor;
import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
import org.hibernate.dialect.DerbyTenSevenDialect;
import org.hibernate.dialect.PostgreSQL94Dialect; import org.hibernate.dialect.PostgreSQL94Dialect;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -95,11 +94,9 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName("PU_HapiFhirJpaDstu2"); retVal.setPersistenceUnitName("PU_HapiFhirJpaDstu2");
retVal.setDataSource(dataSource()); retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(jpaProperties()); retVal.setJpaProperties(jpaProperties());
return retVal; return retVal;
} }
@ -107,7 +104,7 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
private Properties jpaProperties() { private Properties jpaProperties() {
Properties extraProperties = new Properties(); Properties extraProperties = new Properties();
if (CommonConfig.isLocalTestMode()) { if (CommonConfig.isLocalTestMode()) {
extraProperties.put("hibernate.dialect", DerbyTenSevenDialect.class.getName()); extraProperties.put("hibernate.dialect", DerbyTenSevenHapiFhirDialect.class.getName());
} else { } else {
extraProperties.put("hibernate.dialect", PostgreSQL94Dialect.class.getName()); extraProperties.put("hibernate.dialect", PostgreSQL94Dialect.class.getName());
} }

View File

@ -1,31 +1,32 @@
package ca.uhn.fhirtest.config; package ca.uhn.fhirtest.config;
import java.util.Properties; import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu3;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import javax.persistence.EntityManagerFactory; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import javax.sql.DataSource;
import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory; import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory;
import ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
import ca.uhn.fhir.validation.ResultSeverityEnum;
import ca.uhn.fhirtest.interceptor.PublicSecurityInterceptor;
import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
import org.hibernate.dialect.DerbyTenSevenDialect;
import org.hibernate.dialect.PostgreSQL94Dialect; import org.hibernate.dialect.PostgreSQL94Dialect;
import org.hibernate.jpa.HibernatePersistenceProvider; import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.EnableTransactionManagement;
import ca.uhn.fhir.jpa.config.BaseJavaConfigDstu3; import javax.persistence.EntityManagerFactory;
import ca.uhn.fhir.jpa.dao.DaoConfig; import javax.sql.DataSource;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; import java.util.Properties;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
import ca.uhn.fhir.validation.ResultSeverityEnum;
import ca.uhn.fhirtest.interceptor.PublicSecurityInterceptor;
@Configuration @Configuration
@Import(CommonConfig.class) @Import(CommonConfig.class)
@ -92,11 +93,9 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName("PU_HapiFhirJpaDstu3"); retVal.setPersistenceUnitName("PU_HapiFhirJpaDstu3");
retVal.setDataSource(dataSource()); retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(jpaProperties()); retVal.setJpaProperties(jpaProperties());
return retVal; return retVal;
} }
@ -104,7 +103,7 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 {
private Properties jpaProperties() { private Properties jpaProperties() {
Properties extraProperties = new Properties(); Properties extraProperties = new Properties();
if (CommonConfig.isLocalTestMode()) { if (CommonConfig.isLocalTestMode()) {
extraProperties.put("hibernate.dialect", DerbyTenSevenDialect.class.getName()); extraProperties.put("hibernate.dialect", DerbyTenSevenHapiFhirDialect.class.getName());
} else { } else {
extraProperties.put("hibernate.dialect", PostgreSQL94Dialect.class.getName()); extraProperties.put("hibernate.dialect", PostgreSQL94Dialect.class.getName());
} }

View File

@ -1,31 +1,32 @@
package ca.uhn.fhirtest.config; package ca.uhn.fhirtest.config;
import java.util.Properties; import ca.uhn.fhir.jpa.config.BaseJavaConfigR4;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import javax.persistence.EntityManagerFactory; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import javax.sql.DataSource;
import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory; import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory;
import ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
import ca.uhn.fhir.validation.ResultSeverityEnum;
import ca.uhn.fhirtest.interceptor.PublicSecurityInterceptor;
import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
import org.hibernate.dialect.DerbyTenSevenDialect;
import org.hibernate.dialect.PostgreSQL94Dialect; import org.hibernate.dialect.PostgreSQL94Dialect;
import org.hibernate.jpa.HibernatePersistenceProvider; import org.hibernate.jpa.HibernatePersistenceProvider;
import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.EnableTransactionManagement;
import ca.uhn.fhir.jpa.config.BaseJavaConfigR4; import javax.persistence.EntityManagerFactory;
import ca.uhn.fhir.jpa.dao.DaoConfig; import javax.sql.DataSource;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; import java.util.Properties;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
import ca.uhn.fhir.validation.ResultSeverityEnum;
import ca.uhn.fhirtest.interceptor.PublicSecurityInterceptor;
@Configuration @Configuration
@Import(CommonConfig.class) @Import(CommonConfig.class)
@ -87,11 +88,9 @@ public class TestR4Config extends BaseJavaConfigR4 {
@Bean() @Bean()
public LocalContainerEntityManagerFactoryBean entityManagerFactory() { public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean retVal = new LocalContainerEntityManagerFactoryBean(); LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
retVal.setPersistenceUnitName("PU_HapiFhirJpaR4"); retVal.setPersistenceUnitName("PU_HapiFhirJpaR4");
retVal.setDataSource(dataSource()); retVal.setDataSource(dataSource());
retVal.setPackagesToScan("ca.uhn.fhir.jpa.entity");
retVal.setPersistenceProvider(new HibernatePersistenceProvider());
retVal.setJpaProperties(jpaProperties()); retVal.setJpaProperties(jpaProperties());
return retVal; return retVal;
} }
@ -99,7 +98,7 @@ public class TestR4Config extends BaseJavaConfigR4 {
private Properties jpaProperties() { private Properties jpaProperties() {
Properties extraProperties = new Properties(); Properties extraProperties = new Properties();
if (CommonConfig.isLocalTestMode()) { if (CommonConfig.isLocalTestMode()) {
extraProperties.put("hibernate.dialect", DerbyTenSevenDialect.class.getName()); extraProperties.put("hibernate.dialect", DerbyTenSevenHapiFhirDialect.class.getName());
} else { } else {
extraProperties.put("hibernate.dialect", PostgreSQL94Dialect.class.getName()); extraProperties.put("hibernate.dialect", PostgreSQL94Dialect.class.getName());
} }

View File

@ -48,7 +48,7 @@
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" /> <property name="showSql" value="false" />
<property name="generateDdl" value="true" /> <property name="generateDdl" value="true" />
<property name="databasePlatform" value="org.hibernate.dialect.DerbyTenSevenDialect" /> <property name="databasePlatform" value="ca.uhn.fhir.jpa.util.DerbyTenSevenHapiFhirDialect" />
</bean> </bean>
</property> </property>
</bean> </bean>

View File

@ -145,6 +145,11 @@
The HAPI FHIR CLI now supports importing an IGPack file as an import The HAPI FHIR CLI now supports importing an IGPack file as an import
to the validation process. to the validation process.
</action> </action>
<action type="add">
When two threads attempt to update the same resource at the same time, previously
an unspecified error was thrown by the JPA server. An HTTP 412
(Precondition Failed) with an informative error message is now thrown.
</action>
</release> </release>
<release version="3.3.0" date="2018-03-29"> <release version="3.3.0" date="2018-03-29">
<action type="add"> <action type="add">