es = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD);
- securityFilter.addMappingForUrlPatterns(es, true, "/*");
- }
-}
diff --git a/src/main/java/cz/cvut/kbss/study/config/PersistenceConfig.java b/src/main/java/cz/cvut/kbss/study/config/PersistenceConfig.java
index 305adca6..6f4ead9e 100644
--- a/src/main/java/cz/cvut/kbss/study/config/PersistenceConfig.java
+++ b/src/main/java/cz/cvut/kbss/study/config/PersistenceConfig.java
@@ -1,9 +1,24 @@
package cz.cvut.kbss.study.config;
-import org.springframework.context.annotation.ComponentScan;
+import com.github.ledsoft.jopa.spring.transaction.DelegatingEntityManager;
+import com.github.ledsoft.jopa.spring.transaction.JopaTransactionManager;
+import cz.cvut.kbss.jopa.model.EntityManagerFactory;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
-@ComponentScan(basePackages = "cz.cvut.kbss.study.persistence")
+@EnableTransactionManagement
public class PersistenceConfig {
+
+ @Bean
+ public DelegatingEntityManager entityManager() {
+ return new DelegatingEntityManager();
+ }
+
+ @Bean(name = "txManager")
+ public PlatformTransactionManager transactionManager(EntityManagerFactory emf, DelegatingEntityManager emProxy) {
+ return new JopaTransactionManager(emf, emProxy);
+ }
}
diff --git a/src/main/java/cz/cvut/kbss/study/config/RestConfig.java b/src/main/java/cz/cvut/kbss/study/config/RestConfig.java
deleted file mode 100644
index 44353230..00000000
--- a/src/main/java/cz/cvut/kbss/study/config/RestConfig.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package cz.cvut.kbss.study.config;
-
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-@ComponentScan(basePackages = "cz.cvut.kbss.study.rest")
-public class RestConfig {
-
- @Bean
- public ObjectMapper objectMapper() {
- final ObjectMapper objectMapper = new ObjectMapper();
- objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- return objectMapper;
- }
-}
diff --git a/src/main/java/cz/cvut/kbss/study/config/SecurityConfig.java b/src/main/java/cz/cvut/kbss/study/config/SecurityConfig.java
index c7292512..32e1dabf 100644
--- a/src/main/java/cz/cvut/kbss/study/config/SecurityConfig.java
+++ b/src/main/java/cz/cvut/kbss/study/config/SecurityConfig.java
@@ -2,20 +2,23 @@
import cz.cvut.kbss.study.security.CsrfHeaderFilter;
import cz.cvut.kbss.study.security.SecurityConstants;
+import cz.cvut.kbss.study.service.ConfigReader;
+import cz.cvut.kbss.study.util.ConfigParam;
import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
+import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
+import org.springframework.security.web.authentication.HttpStatusEntryPoint;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.web.cors.CorsConfiguration;
@@ -23,12 +26,12 @@
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.Collections;
+import java.util.List;
@Configuration
@EnableWebSecurity
-@ComponentScan(basePackages = "cz.cvut.kbss.study.security")
-@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
-public class SecurityConfig extends WebSecurityConfigurerAdapter {
+@EnableMethodSecurity
+public class SecurityConfig {
private static final String[] COOKIES_TO_DESTROY = {
SecurityConstants.SESSION_COOKIE_NAME,
@@ -36,8 +39,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
SecurityConstants.CSRF_COOKIE_NAME
};
- private final AuthenticationEntryPoint authenticationEntryPoint;
-
private final AuthenticationFailureHandler authenticationFailureHandler;
private final AuthenticationSuccessHandler authenticationSuccessHandler;
@@ -46,56 +47,52 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final AuthenticationProvider ontologyAuthenticationProvider;
- public SecurityConfig(AuthenticationEntryPoint authenticationEntryPoint,
- AuthenticationFailureHandler authenticationFailureHandler,
+ public SecurityConfig(AuthenticationFailureHandler authenticationFailureHandler,
AuthenticationSuccessHandler authenticationSuccessHandler,
LogoutSuccessHandler logoutSuccessHandler,
AuthenticationProvider ontologyAuthenticationProvider) {
- this.authenticationEntryPoint = authenticationEntryPoint;
this.authenticationFailureHandler = authenticationFailureHandler;
this.authenticationSuccessHandler = authenticationSuccessHandler;
this.logoutSuccessHandler = logoutSuccessHandler;
this.ontologyAuthenticationProvider = ontologyAuthenticationProvider;
}
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- auth.authenticationProvider(ontologyAuthenticationProvider);
- }
-
@Bean
- @Override
- public AuthenticationManager authenticationManagerBean() throws Exception {
- return super.authenticationManagerBean();
+ public SecurityFilterChain filterChain(HttpSecurity http, ConfigReader config) throws Exception {
+ final AuthenticationManager authManager = buildAuthenticationManager(http);
+ http.authorizeHttpRequests((auth) -> auth.anyRequest().permitAll())
+ .cors((auth) -> auth.configurationSource(corsConfigurationSource(config)))
+ .csrf(AbstractHttpConfigurer::disable)
+ .addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
+ .exceptionHandling(ehc -> ehc.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)))
+ .formLogin((form) -> form.loginProcessingUrl(SecurityConstants.SECURITY_CHECK_URI)
+ .successHandler(authenticationSuccessHandler)
+ .failureHandler(authenticationFailureHandler))
+ .logout((auth) -> auth.logoutUrl(SecurityConstants.LOGOUT_URI)
+ .logoutSuccessHandler(logoutSuccessHandler)
+ .invalidateHttpSession(true).deleteCookies(COOKIES_TO_DESTROY))
+ .authenticationManager(authManager);
+ return http.build();
}
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http.authorizeRequests().anyRequest().permitAll().and()
- .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
- .and().cors().configurationSource(corsConfigurationSource())
- .and()
- .authenticationProvider(ontologyAuthenticationProvider)
- .addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
- .csrf().disable()
- .formLogin().successHandler(authenticationSuccessHandler)
- .failureHandler(authenticationFailureHandler)
- .loginProcessingUrl(SecurityConstants.SECURITY_CHECK_URI)
- .usernameParameter(SecurityConstants.USERNAME_PARAM).passwordParameter(SecurityConstants.PASSWORD_PARAM)
- .and()
- .logout().invalidateHttpSession(true).deleteCookies(COOKIES_TO_DESTROY)
- .logoutUrl(SecurityConstants.LOGOUT_URI).logoutSuccessHandler(logoutSuccessHandler)
- .and().sessionManagement().maximumSessions(1);
+ private AuthenticationManager buildAuthenticationManager(HttpSecurity http) throws Exception {
+ final AuthenticationManagerBuilder ab = http.getSharedObject(AuthenticationManagerBuilder.class);
+ ab.authenticationProvider(ontologyAuthenticationProvider);
+ return ab.build();
}
@Bean
- CorsConfigurationSource corsConfigurationSource() {
- // We're allowing all methods from all origins so that the application API is usable also by other clients
- // than just the UI.
- // This behavior can be restricted later.
+ CorsConfigurationSource corsConfigurationSource(ConfigReader config) {
+ // allowCredentials requires allowed origins to be configured (* is not supported)
final CorsConfiguration corsConfiguration = new CorsConfiguration().applyPermitDefaultValues();
corsConfiguration.setAllowedMethods(Collections.singletonList("*"));
- corsConfiguration.setAllowedOrigins(Collections.singletonList("*"));
+ if (!config.getConfig(ConfigParam.APP_CONTEXT, "").isBlank()) {
+ String appUrl = config.getConfig(ConfigParam.APP_CONTEXT);
+ appUrl = appUrl.substring(0, appUrl.lastIndexOf('/'));
+ corsConfiguration.setAllowedOrigins(List.of(appUrl));
+ } else {
+ corsConfiguration.setAllowedOrigins(Collections.singletonList("*"));
+ }
corsConfiguration.addExposedHeader(HttpHeaders.AUTHORIZATION);
corsConfiguration.addExposedHeader(HttpHeaders.LOCATION);
corsConfiguration.addExposedHeader(HttpHeaders.CONTENT_DISPOSITION);
diff --git a/src/main/java/cz/cvut/kbss/study/config/ServiceConfig.java b/src/main/java/cz/cvut/kbss/study/config/ServiceConfig.java
index 35150732..d5dec886 100644
--- a/src/main/java/cz/cvut/kbss/study/config/ServiceConfig.java
+++ b/src/main/java/cz/cvut/kbss/study/config/ServiceConfig.java
@@ -1,14 +1,23 @@
package cz.cvut.kbss.study.config;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.hc.client5.http.classic.HttpClient;
+import org.apache.hc.client5.http.impl.DefaultRedirectStrategy;
+import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.http.converter.ResourceHttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.client.RestTemplate;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
@Configuration
-@ComponentScan(basePackages = "cz.cvut.kbss.study.service")
public class ServiceConfig {
@Bean
@@ -17,7 +26,22 @@ public PasswordEncoder passwordEncoder() {
}
@Bean
- public RestTemplate restTemplate() {
- return new RestTemplate();
+ public RestTemplate restTemplate(ObjectMapper objectMapper) {
+ final RestTemplate restTemplate = new RestTemplate();
+
+ // HttpClient 5 default redirect strategy automatically follows POST redirects as well
+ final HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
+ final HttpClient httpClient = HttpClientBuilder.create()
+ .setRedirectStrategy(new DefaultRedirectStrategy())
+ .build();
+ factory.setHttpClient(httpClient);
+ restTemplate.setRequestFactory(factory);
+
+ final MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();
+ jacksonConverter.setObjectMapper(objectMapper);
+ final StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
+ restTemplate.setMessageConverters(
+ Arrays.asList(stringConverter, jacksonConverter, new ResourceHttpMessageConverter()));
+ return restTemplate;
}
}
diff --git a/src/main/java/cz/cvut/kbss/study/config/WebAppConfig.java b/src/main/java/cz/cvut/kbss/study/config/WebAppConfig.java
index 59f02316..df53da8b 100644
--- a/src/main/java/cz/cvut/kbss/study/config/WebAppConfig.java
+++ b/src/main/java/cz/cvut/kbss/study/config/WebAppConfig.java
@@ -3,48 +3,56 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import cz.cvut.kbss.jopa.sessions.UnitOfWorkImpl;
+import cz.cvut.kbss.study.rest.servlet.DiagnosticsContextFilter;
import cz.cvut.kbss.study.util.Constants;
+import cz.cvut.kbss.study.util.json.ManageableIgnoreMixin;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
+import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.ResourceHttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.method.HandlerTypePredicate;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
-import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
-import org.springframework.web.servlet.config.annotation.EnableWebMvc;
-import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
-import org.springframework.web.servlet.view.InternalResourceViewResolver;
-import org.springframework.web.servlet.view.JstlView;
+import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-import java.nio.charset.Charset;
-import java.util.List;
+import java.nio.charset.StandardCharsets;
@Configuration
-@EnableWebMvc
-@Import({RestConfig.class, SecurityConfig.class})
-public class WebAppConfig extends WebMvcConfigurerAdapter {
+public class WebAppConfig implements WebMvcConfigurer {
- @Override
- public void addResourceHandlers(ResourceHandlerRegistry registry) {
- registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
- registry.addResourceHandler("/js/**").addResourceLocations("/js/");
- }
-
- @Override
- public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
- configurer.enable();
+ @Bean(name = "objectMapper")
+ @Primary
+ public ObjectMapper objectMapper() {
+ return createJsonObjectMapper();
}
- @Bean
- public InternalResourceViewResolver setupViewResolver() {
- InternalResourceViewResolver resolver = new InternalResourceViewResolver();
- resolver.setViewClass(JstlView.class);
- resolver.setPrefix("/WEB-INF/");
- resolver.setSuffix(".html");
- return resolver;
+ /**
+ * Creates an {@link ObjectMapper} for processing regular JSON.
+ *
+ * This method is public static so that it can be used by the test environment as well.
+ *
+ * @return {@code ObjectMapper} instance
+ */
+ public static ObjectMapper createJsonObjectMapper() {
+ final ObjectMapper objectMapper = new ObjectMapper();
+ objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
+ objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ // Ignore UoW references injected into entities
+ objectMapper.addMixIn(UnitOfWorkImpl.class, ManageableIgnoreMixin.class);
+ // JSR 310 (Java 8 DateTime API)
+ objectMapper.registerModule(new JavaTimeModule());
+ // Serialize datetime as ISO strings
+ objectMapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
+ return objectMapper;
}
@Bean(name = "multipartResolver")
@@ -52,17 +60,36 @@ public MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
- @Override
- public void configureMessageConverters(List> converters) {
+ @Bean
+ public HttpMessageConverter> stringMessageConverter() {
+ return new StringHttpMessageConverter(StandardCharsets.UTF_8);
+ }
+
+ @Bean
+ public HttpMessageConverter> jsonMessageConverter(ObjectMapper objectMapper) {
final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
- final ObjectMapper objectMapper = new ObjectMapper();
- objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
- objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
converter.setObjectMapper(objectMapper);
- converters.add(converter);
- final StringHttpMessageConverter stringConverter = new StringHttpMessageConverter(Charset.forName(
- Constants.UTF_8_ENCODING));
- converters.add(stringConverter);
- super.configureMessageConverters(converters);
+ return converter;
+ }
+
+ @Bean
+ public HttpMessageConverter> resourceMessageConverter() {
+ return new ResourceHttpMessageConverter();
+ }
+
+ /**
+ * Registers a filter that allows using current user's username in log pattern.
+ */
+ @Bean
+ public FilterRegistrationBean mdcFilter() {
+ FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
+ registrationBean.setFilter(new DiagnosticsContextFilter());
+ registrationBean.addUrlPatterns("/*");
+ return registrationBean;
+ }
+
+ @Override
+ public void configurePathMatch(PathMatchConfigurer matcher) {
+ matcher.addPathPrefix(Constants.REST_API_REFIX, HandlerTypePredicate.forAnnotation(RestController.class));
}
}
diff --git a/src/main/java/cz/cvut/kbss/study/persistence/FormGenPersistenceFactory.java b/src/main/java/cz/cvut/kbss/study/persistence/FormGenPersistenceFactory.java
index 358409c5..bad6ff41 100644
--- a/src/main/java/cz/cvut/kbss/study/persistence/FormGenPersistenceFactory.java
+++ b/src/main/java/cz/cvut/kbss/study/persistence/FormGenPersistenceFactory.java
@@ -2,18 +2,19 @@
import cz.cvut.kbss.jopa.Persistence;
import cz.cvut.kbss.jopa.model.EntityManagerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
import java.util.HashMap;
import java.util.Map;
-import static cz.cvut.kbss.jopa.model.JOPAPersistenceProperties.*;
+import static cz.cvut.kbss.jopa.model.JOPAPersistenceProperties.CACHE_ENABLED;
+import static cz.cvut.kbss.jopa.model.JOPAPersistenceProperties.DATA_SOURCE_CLASS;
+import static cz.cvut.kbss.jopa.model.JOPAPersistenceProperties.ONTOLOGY_PHYSICAL_URI_KEY;
import static cz.cvut.kbss.study.util.ConfigParam.DRIVER;
import static cz.cvut.kbss.study.util.ConfigParam.FORM_GEN_REPOSITORY_URL;
diff --git a/src/main/java/cz/cvut/kbss/study/persistence/PersistenceFactory.java b/src/main/java/cz/cvut/kbss/study/persistence/PersistenceFactory.java
index 3f6ed437..9cc8f31d 100644
--- a/src/main/java/cz/cvut/kbss/study/persistence/PersistenceFactory.java
+++ b/src/main/java/cz/cvut/kbss/study/persistence/PersistenceFactory.java
@@ -3,22 +3,24 @@
import cz.cvut.kbss.jopa.Persistence;
import cz.cvut.kbss.jopa.model.EntityManagerFactory;
import cz.cvut.kbss.jopa.model.JOPAPersistenceProvider;
-import cz.cvut.kbss.ontodriver.config.OntoDriverProperties;
import cz.cvut.kbss.study.util.Constants;
-import org.springframework.beans.factory.annotation.Autowired;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
-import static cz.cvut.kbss.jopa.model.JOPAPersistenceProperties.*;
+import static cz.cvut.kbss.jopa.model.JOPAPersistenceProperties.DATA_SOURCE_CLASS;
+import static cz.cvut.kbss.jopa.model.JOPAPersistenceProperties.JPA_PERSISTENCE_PROVIDER;
+import static cz.cvut.kbss.jopa.model.JOPAPersistenceProperties.LANG;
+import static cz.cvut.kbss.jopa.model.JOPAPersistenceProperties.ONTOLOGY_PHYSICAL_URI_KEY;
+import static cz.cvut.kbss.jopa.model.JOPAPersistenceProperties.SCAN_PACKAGE;
import static cz.cvut.kbss.ontodriver.config.OntoDriverProperties.DATA_SOURCE_PASSWORD;
import static cz.cvut.kbss.ontodriver.config.OntoDriverProperties.DATA_SOURCE_USERNAME;
import static cz.cvut.kbss.study.util.ConfigParam.DRIVER;
@@ -69,7 +71,7 @@ private void close() {
private static Map initParams() {
final Map map = new HashMap<>();
- map.put(OntoDriverProperties.ONTOLOGY_LANGUAGE, Constants.PU_LANGUAGE);
+ map.put(LANG, Constants.PU_LANGUAGE);
map.put(SCAN_PACKAGE, "cz.cvut.kbss.study");
map.put(JPA_PERSISTENCE_PROVIDER, JOPAPersistenceProvider.class.getName());
return map;
diff --git a/src/main/java/cz/cvut/kbss/study/persistence/dao/ActionHistoryDao.java b/src/main/java/cz/cvut/kbss/study/persistence/dao/ActionHistoryDao.java
index 5fea7433..ad377150 100644
--- a/src/main/java/cz/cvut/kbss/study/persistence/dao/ActionHistoryDao.java
+++ b/src/main/java/cz/cvut/kbss/study/persistence/dao/ActionHistoryDao.java
@@ -2,7 +2,7 @@
import cz.cvut.kbss.jopa.exceptions.NoResultException;
import cz.cvut.kbss.jopa.model.EntityManager;
-import cz.cvut.kbss.jopa.model.query.Query;
+import cz.cvut.kbss.jopa.model.query.TypedQuery;
import cz.cvut.kbss.study.model.ActionHistory;
import cz.cvut.kbss.study.model.User;
import cz.cvut.kbss.study.model.Vocabulary;
@@ -14,27 +14,24 @@
import java.util.Objects;
@Repository
-public class ActionHistoryDao extends OwlKeySupportingDao{
+public class ActionHistoryDao extends OwlKeySupportingDao {
- public ActionHistoryDao() {
- super(ActionHistory.class);
+ public ActionHistoryDao(EntityManager em) {
+ super(ActionHistory.class, em);
}
public ActionHistory findByKey(String key) {
Objects.requireNonNull(key);
- final EntityManager em = entityManager();
try {
ActionHistory action = em.createNativeQuery(
- "SELECT ?x WHERE { ?x ?hasKey ?key . }", ActionHistory.class)
- .setParameter("hasKey", URI.create(Vocabulary.s_p_key))
- .setParameter("key", key, Constants.PU_LANGUAGE)
- .getSingleResult();
+ "SELECT ?x WHERE { ?x ?hasKey ?key . }", ActionHistory.class)
+ .setParameter("hasKey", URI.create(Vocabulary.s_p_key))
+ .setParameter("key", key, Constants.PU_LANGUAGE)
+ .getSingleResult();
action.getPayload();
return action;
} catch (NoResultException e) {
return null;
- } finally {
- em.close();
}
}
@@ -51,26 +48,22 @@ public List findAllWithParams(String typeFilter, User author, int
} else {
params = "; ?hasOwner ?author; ?isType ?actionType . filter contains(?actionType, ?typeFilter) } ";
}
- final EntityManager em = entityManager();
- try {
- Query q = em.createNativeQuery("SELECT ?r WHERE { ?r a ?type ; ?isCreated ?timestamp " +
- params + "ORDER BY DESC(?timestamp)", ActionHistory.class)
- .setParameter("type", typeUri)
- .setParameter("isCreated", URI.create(Vocabulary.s_p_created))
- .setFirstResult((pageNumber - 1) * Constants.ACTIONS_PER_PAGE)
- .setMaxResults(Constants.ACTIONS_PER_PAGE + 1);
+ TypedQuery q = em.createNativeQuery("SELECT ?r WHERE { ?r a ?type ; ?isCreated ?timestamp " +
+ params + "ORDER BY DESC(?timestamp)",
+ ActionHistory.class)
+ .setParameter("type", typeUri)
+ .setParameter("isCreated", URI.create(Vocabulary.s_p_created))
+ .setFirstResult((pageNumber - 1) * Constants.ACTIONS_PER_PAGE)
+ .setMaxResults(Constants.ACTIONS_PER_PAGE + 1);
- if (author != null) {
- q.setParameter("hasOwner", URI.create(Vocabulary.s_p_has_owner))
- .setParameter("author", author.getUri());
- }
- if (typeFilter != null) {
- q.setParameter("typeFilter", typeFilter, Constants.PU_LANGUAGE)
- .setParameter("isType", URI.create(Vocabulary.s_p_action_type));
- }
- return q.getResultList();
- } finally {
- em.close();
+ if (author != null) {
+ q.setParameter("hasOwner", URI.create(Vocabulary.s_p_has_owner))
+ .setParameter("author", author.getUri());
+ }
+ if (typeFilter != null) {
+ q.setParameter("typeFilter", typeFilter, Constants.PU_LANGUAGE)
+ .setParameter("isType", URI.create(Vocabulary.s_p_action_type));
}
+ return q.getResultList();
}
}
diff --git a/src/main/java/cz/cvut/kbss/study/persistence/dao/BaseDao.java b/src/main/java/cz/cvut/kbss/study/persistence/dao/BaseDao.java
index 380479d2..7b3f550a 100644
--- a/src/main/java/cz/cvut/kbss/study/persistence/dao/BaseDao.java
+++ b/src/main/java/cz/cvut/kbss/study/persistence/dao/BaseDao.java
@@ -1,13 +1,11 @@
package cz.cvut.kbss.study.persistence.dao;
import cz.cvut.kbss.jopa.model.EntityManager;
-import cz.cvut.kbss.jopa.model.EntityManagerFactory;
import cz.cvut.kbss.jopa.model.annotations.OWLClass;
import cz.cvut.kbss.study.exception.PersistenceException;
import cz.cvut.kbss.study.model.util.EntityToOwlClassMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import java.net.URI;
import java.util.Collection;
@@ -24,37 +22,24 @@ public abstract class BaseDao implements GenericDao {
protected final Class type;
final URI typeUri;
- protected BaseDao(Class type) {
+ protected final EntityManager em;
+
+ protected BaseDao(Class type, EntityManager em) {
this.type = type;
this.typeUri = URI.create(EntityToOwlClassMapper.getOwlClassForEntity(type));
+ this.em = em;
}
- @Autowired
- private EntityManagerFactory emf;
-
@Override
public T find(URI uri) {
Objects.requireNonNull(uri);
- final EntityManager em = entityManager();
- try {
- return findByUri(uri, em);
- } finally {
- em.close();
- }
- }
-
- protected T findByUri(URI uri, EntityManager em) {
- return em.find(type, uri);
+ return em.find(type, uri);
}
@Override
public List findAll() {
- final EntityManager em = entityManager();
- try {
- return findAll(em);
- } finally {
- em.close();
- }
+ return em.createNativeQuery("SELECT ?x WHERE { ?x a ?type . }", type).setParameter("type", typeUri)
+ .getResultList();
}
protected List findAll(EntityManager em) {
@@ -65,120 +50,58 @@ protected List findAll(EntityManager em) {
@Override
public void persist(T entity) {
Objects.requireNonNull(entity);
- final EntityManager em = entityManager();
try {
- em.getTransaction().begin();
- persist(entity, em);
- em.getTransaction().commit();
+ em.persist(entity);
} catch (RuntimeException e) {
LOG.error("Error when persisting entity.", e);
throw new PersistenceException(e);
- } finally {
- em.close();
}
}
- protected void persist(T entity, EntityManager em) {
- em.persist(entity);
- }
-
@Override
public void persist(Collection entities) {
Objects.requireNonNull(entities);
if (entities.isEmpty()) {
return;
}
- final EntityManager em = entityManager();
- try {
- em.getTransaction().begin();
- entities.forEach(e -> persist(e, em));
- em.getTransaction().commit();
- } catch (RuntimeException e) {
- LOG.error("Error when persisting entities.", e);
- throw new PersistenceException(e);
- } finally {
- em.close();
- }
+ entities.forEach(this::persist);
}
@Override
public void update(T entity) {
Objects.requireNonNull(entity);
- final EntityManager em = entityManager();
try {
- em.getTransaction().begin();
- update(entity, em);
- em.getTransaction().commit();
+ em.merge(entity);
} catch (RuntimeException e) {
LOG.error("Error when updating entity.", e);
throw new PersistenceException(e);
- } finally {
- em.close();
}
}
- protected void update(T entity, EntityManager em) {
- em.merge(entity);
- }
-
@Override
public void remove(T entity) {
Objects.requireNonNull(entity);
- final EntityManager em = entityManager();
try {
- em.getTransaction().begin();
- remove(entity, em);
- em.getTransaction().commit();
+ final T toRemove = em.merge(entity);
+ assert toRemove != null;
+ em.remove(toRemove);
} catch (RuntimeException e) {
LOG.error("Error when removing entity.", e);
throw new PersistenceException(e);
- } finally {
- em.close();
}
}
- protected void remove(T entity, EntityManager em) {
- final T toRemove = em.merge(entity);
- assert toRemove != null;
- em.remove(toRemove);
- }
-
@Override
public void remove(Collection entities) {
Objects.requireNonNull(entities);
if (entities.isEmpty()) {
return;
}
- final EntityManager em = entityManager();
- try {
- em.getTransaction().begin();
- entities.forEach(entity -> {
- final T toRemove = em.merge(entity);
- em.remove(toRemove);
- });
- em.getTransaction().commit();
- } catch (RuntimeException e) {
- LOG.error("Error when removing entities.", e);
- throw new PersistenceException(e);
- } finally {
- em.close();
- }
+ entities.forEach(this::remove);
}
@Override
public boolean exists(URI uri) {
- if (uri == null) {
- return false;
- }
- final EntityManager em = entityManager();
- try {
- return exists(uri, em);
- } finally {
- em.close();
- }
- }
-
- protected boolean exists(URI uri, EntityManager em) {
if (uri == null) {
return false;
}
@@ -186,8 +109,4 @@ protected boolean exists(URI uri, EntityManager em) {
return em.createNativeQuery("ASK { ?individual a ?type . }", Boolean.class).setParameter("individual", uri)
.setParameter("type", URI.create(owlClass)).getSingleResult();
}
-
- EntityManager entityManager() {
- return emf.createEntityManager();
- }
}
diff --git a/src/main/java/cz/cvut/kbss/study/persistence/dao/DerivableUriDao.java b/src/main/java/cz/cvut/kbss/study/persistence/dao/DerivableUriDao.java
index fa23c3a0..acfc4c74 100644
--- a/src/main/java/cz/cvut/kbss/study/persistence/dao/DerivableUriDao.java
+++ b/src/main/java/cz/cvut/kbss/study/persistence/dao/DerivableUriDao.java
@@ -3,6 +3,8 @@
import cz.cvut.kbss.jopa.model.EntityManager;
import cz.cvut.kbss.study.model.util.HasDerivableUri;
+import java.util.Objects;
+
/**
* Data access object for classes with derivable URI.
*
@@ -12,20 +14,19 @@
*/
abstract class DerivableUriDao extends BaseDao {
- protected DerivableUriDao(Class type) {
- super(type);
+ protected DerivableUriDao(Class type, EntityManager em) {
+ super(type, em);
}
/**
* Generates URI and then calls persist.
*
* @param entity Entity to persist
- * @param em Current entity manager
*/
@Override
- protected void persist(T entity, EntityManager em) {
- assert entity != null;
+ public void persist(T entity) {
+ Objects.requireNonNull(entity);
entity.generateUri();
- super.persist(entity, em);
+ super.persist(entity);
}
}
diff --git a/src/main/java/cz/cvut/kbss/study/persistence/dao/InstitutionDao.java b/src/main/java/cz/cvut/kbss/study/persistence/dao/InstitutionDao.java
index a6780454..448ecc57 100644
--- a/src/main/java/cz/cvut/kbss/study/persistence/dao/InstitutionDao.java
+++ b/src/main/java/cz/cvut/kbss/study/persistence/dao/InstitutionDao.java
@@ -12,8 +12,8 @@
@Repository
public class InstitutionDao extends OwlKeySupportingDao {
- public InstitutionDao() {
- super(Institution.class);
+ public InstitutionDao(EntityManager em) {
+ super(Institution.class, em);
}
/**
@@ -26,15 +26,12 @@ public Institution findByName(String name) {
if (name == null) {
return null;
}
- final EntityManager em = entityManager();
try {
return em.createNativeQuery("SELECT ?x WHERE { ?x ?hasName ?name . }", Institution.class)
.setParameter("hasName", URI.create(Vocabulary.s_p_label))
.setParameter("name", name, Constants.PU_LANGUAGE).getSingleResult();
} catch (NoResultException e) {
return null;
- } finally {
- em.close();
}
}
}
diff --git a/src/main/java/cz/cvut/kbss/study/persistence/dao/OwlKeySupportingDao.java b/src/main/java/cz/cvut/kbss/study/persistence/dao/OwlKeySupportingDao.java
index 627a3d2f..a0d03383 100644
--- a/src/main/java/cz/cvut/kbss/study/persistence/dao/OwlKeySupportingDao.java
+++ b/src/main/java/cz/cvut/kbss/study/persistence/dao/OwlKeySupportingDao.java
@@ -17,21 +17,20 @@
*/
public abstract class OwlKeySupportingDao extends BaseDao {
- protected OwlKeySupportingDao(Class type) {
- super(type);
+ protected OwlKeySupportingDao(Class type, EntityManager em) {
+ super(type, em);
}
/**
* Generates key and then calls persist.
*
* @param entity The instance to persist
- * @param em Current EntityManager
*/
@Override
- protected void persist(T entity, EntityManager em) {
- assert entity != null;
+ public void persist(T entity) {
+ Objects.requireNonNull(entity);
entity.setKey(IdentificationUtils.generateKey());
- super.persist(entity, em);
+ super.persist(entity);
}
/**
@@ -42,18 +41,9 @@ protected void persist(T entity, EntityManager em) {
*/
public T findByKey(String key) {
Objects.requireNonNull(key);
- final EntityManager em = entityManager();
- try {
- return findByKey(key, em);
- } finally {
- em.close();
- }
- }
-
- protected T findByKey(String key, EntityManager em) {
try {
return em.createNativeQuery("SELECT ?x WHERE { ?x ?hasKey ?key ;" +
- "a ?type }", type)
+ "a ?type }", type)
.setParameter("hasKey", URI.create(Vocabulary.s_p_key))
.setParameter("key", key, Constants.PU_LANGUAGE).setParameter("type", typeUri).getSingleResult();
} catch (NoResultException e) {
diff --git a/src/main/java/cz/cvut/kbss/study/persistence/dao/PatientRecordDao.java b/src/main/java/cz/cvut/kbss/study/persistence/dao/PatientRecordDao.java
index 175d33e7..b36ba023 100644
--- a/src/main/java/cz/cvut/kbss/study/persistence/dao/PatientRecordDao.java
+++ b/src/main/java/cz/cvut/kbss/study/persistence/dao/PatientRecordDao.java
@@ -2,16 +2,15 @@
import cz.cvut.kbss.jopa.model.EntityManager;
import cz.cvut.kbss.study.dto.PatientRecordDto;
-import cz.cvut.kbss.study.exception.PersistenceException;
import cz.cvut.kbss.study.exception.ValidationException;
import cz.cvut.kbss.study.model.Institution;
import cz.cvut.kbss.study.model.PatientRecord;
import cz.cvut.kbss.study.model.User;
import cz.cvut.kbss.study.model.Vocabulary;
import cz.cvut.kbss.study.persistence.dao.util.QuestionSaver;
-import java.math.BigInteger;
import org.springframework.stereotype.Repository;
+import java.math.BigInteger;
import java.net.URI;
import java.util.List;
import java.util.Objects;
@@ -19,20 +18,20 @@
@Repository
public class PatientRecordDao extends OwlKeySupportingDao {
- public PatientRecordDao() {
- super(PatientRecord.class);
+ public PatientRecordDao(EntityManager em) {
+ super(PatientRecord.class, em);
}
@Override
- protected void persist(PatientRecord entity, EntityManager em) {
- assert entity != null;
- super.persist(entity, em);
+ public void persist(PatientRecord entity) {
+ super.persist(entity);
final QuestionSaver questionSaver = new QuestionSaver();
questionSaver.persistIfNecessary(entity.getQuestion(), em);
}
@Override
- protected void update(PatientRecord entity, EntityManager em) {
+ public void update(PatientRecord entity) {
+ Objects.requireNonNull(entity);
final PatientRecord orig = em.find(PatientRecord.class, entity.getUri());
assert orig != null;
orig.setQuestion(null);
@@ -40,12 +39,9 @@ protected void update(PatientRecord entity, EntityManager em) {
}
public List findAllRecords() {
- final EntityManager em = entityManager();
- try {
- return findAllRecords(em);
- } finally {
- em.close();
- }
+ return em.createNativeQuery("SELECT ?x WHERE { ?x a ?type . }", PatientRecordDto.class)
+ .setParameter("type", typeUri)
+ .getResultList();
}
/**
@@ -56,16 +52,12 @@ public List findAllRecords() {
*/
public List findByInstitution(Institution institution) {
Objects.requireNonNull(institution);
- final EntityManager em = entityManager();
- try {
- return em.createNativeQuery("SELECT ?r WHERE { ?r a ?type ; ?treatedAt ?institution . }", PatientRecordDto.class)
- .setParameter("type", typeUri)
- .setParameter("treatedAt", URI.create(Vocabulary.s_p_was_treated_at))
- .setParameter("institution", institution.getUri())
- .getResultList();
- } finally {
- em.close();
- }
+ return em.createNativeQuery("SELECT ?r WHERE { ?r a ?type ; ?treatedAt ?institution . }",
+ PatientRecordDto.class)
+ .setParameter("type", typeUri)
+ .setParameter("treatedAt", URI.create(Vocabulary.s_p_was_treated_at))
+ .setParameter("institution", institution.getUri())
+ .getResultList();
}
/**
@@ -76,56 +68,40 @@ public List findByInstitution(Institution institution) {
*/
public List findByAuthor(User author) {
Objects.requireNonNull(author);
- final EntityManager em = entityManager();
- try {
- return em.createNativeQuery("SELECT ?r WHERE { ?r a ?type ; ?createdBy ?author . }", PatientRecord.class)
- .setParameter("type", typeUri)
- .setParameter("createdBy", URI.create(Vocabulary.s_p_has_author))
- .setParameter("author", author.getUri()).getResultList();
- } finally {
- em.close();
- }
+ return em.createNativeQuery("SELECT ?r WHERE { ?r a ?type ; ?createdBy ?author . }", PatientRecord.class)
+ .setParameter("type", typeUri)
+ .setParameter("createdBy", URI.create(Vocabulary.s_p_has_author))
+ .setParameter("author", author.getUri()).getResultList();
}
public int getNumberOfProcessedRecords() {
- final EntityManager em = entityManager();
- try {
- return ((BigInteger) em.createNativeQuery(
- "SELECT (count(?p) as ?patientRecordsCount) WHERE { ?p a ?record . }")
- .setParameter("record", URI.create(Vocabulary.s_c_patient_record))
- .getSingleResult()
- ).intValue();
- } finally {
- em.close();
- }
- }
-
- private List findAllRecords(EntityManager em) {
- return em.createNativeQuery("SELECT ?x WHERE { ?x a ?type . }", PatientRecordDto.class)
- .setParameter("type", typeUri)
- .getResultList();
+ return ((BigInteger) em.createNativeQuery(
+ "SELECT (count(?p) as ?patientRecordsCount) WHERE { ?p a ?record . }")
+ .setParameter("record", URI.create(Vocabulary.s_c_patient_record))
+ .getSingleResult()
+ ).intValue();
}
/**
* Ensure that local name of provided record is unique within its organization.
*
* @param entity The local name to be checked for uniqueness
- * @return Local names of matching records
*/
public void requireUniqueNonEmptyLocalName(PatientRecord entity) {
Objects.requireNonNull(entity.getInstitution());
if (entity.getLocalName() == null || entity.getLocalName().isEmpty()) {
throw new ValidationException("error.record.localNameOfRecordIsEmpty",
- "Local name of record is empty for entity " + entity);
+ "Local name of record is empty for entity " + entity);
}
boolean unique = findByInstitution(entity.getInstitution()).stream()
- .filter(pr -> (entity.getFormTemplate() != null) && entity.getFormTemplate().equals(pr.getFormTemplate()))
- .filter(pr -> pr.getLocalName()
- .equals(entity.getLocalName()))
- .noneMatch(pr -> ! pr.getUri().equals(entity.getUri()));
- if (! unique) {
+ .filter(pr -> (entity.getFormTemplate() != null) && entity.getFormTemplate()
+ .equals(pr.getFormTemplate()))
+ .filter(pr -> pr.getLocalName()
+ .equals(entity.getLocalName()))
+ .allMatch(pr -> pr.getUri().equals(entity.getUri()));
+ if (!unique) {
throw new ValidationException("error.record.localNameOfRecordIsNotUnique",
- "Local name of record is not unique for entity " + entity);
+ "Local name of record is not unique for entity " + entity);
}
}
diff --git a/src/main/java/cz/cvut/kbss/study/persistence/dao/UserDao.java b/src/main/java/cz/cvut/kbss/study/persistence/dao/UserDao.java
index 564bc2b1..9e461d9f 100644
--- a/src/main/java/cz/cvut/kbss/study/persistence/dao/UserDao.java
+++ b/src/main/java/cz/cvut/kbss/study/persistence/dao/UserDao.java
@@ -6,11 +6,11 @@
import cz.cvut.kbss.study.model.User;
import cz.cvut.kbss.study.model.Vocabulary;
import cz.cvut.kbss.study.util.Constants;
-import java.math.BigInteger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
+import java.math.BigInteger;
import java.net.URI;
import java.util.List;
import java.util.Objects;
@@ -20,58 +20,47 @@ public class UserDao extends DerivableUriDao {
protected static final Logger LOG = LoggerFactory.getLogger(UserDao.class);
- public UserDao() {
- super(User.class);
+ public UserDao(EntityManager em) {
+ super(User.class, em);
}
public User findByUsername(String username) {
Objects.requireNonNull(username);
- final EntityManager em = entityManager();
try {
- return em.createNativeQuery(
- "SELECT ?x WHERE { ?x ?hasUsername ?username . }", User.class)
+ return em.createNativeQuery("SELECT ?x WHERE { ?x ?hasUsername ?username . }", User.class)
.setParameter("hasUsername", URI.create(Vocabulary.s_p_accountName))
.setParameter("username", username, Constants.PU_LANGUAGE)
.getSingleResult();
} catch (NoResultException e) {
return null;
- } finally {
- em.close();
}
}
public User findByEmail(String email) {
Objects.requireNonNull(email);
- final EntityManager em = entityManager();
final String normalizedEmail = email.trim().toLowerCase();
try {
return em.createNativeQuery(
- "SELECT ?x WHERE { " +
- "?x ?hasEmail ?emailAddress . " +
- "FILTER(lcase(?emailAddress) = ?normalizedEmailAddress) }", User.class)
- .setParameter("hasEmail", URI.create(Vocabulary.s_p_mbox))
- .setParameter("normalizedEmailAddress", normalizedEmail, Constants.PU_LANGUAGE)
- .getSingleResult();
+ "SELECT ?x WHERE { " +
+ "?x ?hasEmail ?emailAddress . " +
+ "FILTER(lcase(?emailAddress) = ?normalizedEmailAddress) }", User.class)
+ .setParameter("hasEmail", URI.create(Vocabulary.s_p_mbox))
+ .setParameter("normalizedEmailAddress", normalizedEmail, Constants.PU_LANGUAGE)
+ .getSingleResult();
} catch (NoResultException e) {
return null;
- } finally {
- em.close();
}
}
public User findByToken(String token) {
Objects.requireNonNull(token);
- final EntityManager em = entityManager();
try {
- return em.createNativeQuery(
- "SELECT ?x WHERE { ?x ?valid ?token . }", User.class)
- .setParameter("valid", URI.create(Vocabulary.s_p_token))
- .setParameter("token", token, Constants.PU_LANGUAGE)
- .getSingleResult();
+ return em.createNativeQuery("SELECT ?x WHERE { ?x ?valid ?token . }", User.class)
+ .setParameter("valid", URI.create(Vocabulary.s_p_token))
+ .setParameter("token", token, Constants.PU_LANGUAGE)
+ .getSingleResult();
} catch (NoResultException e) {
return null;
- } finally {
- em.close();
}
}
@@ -83,30 +72,20 @@ public User findByToken(String token) {
*/
public List findByInstitution(Institution institution) {
Objects.requireNonNull(institution);
- final EntityManager em = entityManager();
- try {
- return em.createNativeQuery(
- "SELECT ?x WHERE { ?x a ?type ; ?hasUsername ?username ; ?isMemberOf ?institution . } ORDER BY ?username",
- User.class)
- .setParameter("type", typeUri)
- .setParameter("hasUsername", URI.create(Vocabulary.s_p_accountName))
- .setParameter("isMemberOf", URI.create(Vocabulary.s_p_is_member_of))
- .setParameter("institution", institution.getUri()).getResultList();
- } finally {
- em.close();
- }
+ return em.createNativeQuery(
+ "SELECT ?x WHERE { ?x a ?type ; ?hasUsername ?username ; ?isMemberOf ?institution . } ORDER BY ?username",
+ User.class)
+ .setParameter("type", typeUri)
+ .setParameter("hasUsername", URI.create(Vocabulary.s_p_accountName))
+ .setParameter("isMemberOf", URI.create(Vocabulary.s_p_is_member_of))
+ .setParameter("institution", institution.getUri()).getResultList();
}
public int getNumberOfInvestigators() {
- final EntityManager em = entityManager();
- try {
- return ((BigInteger) em.createNativeQuery(
- "SELECT (count(?p) as ?investigatorCount) WHERE { ?p a ?typeDoctor . MINUS {?p a ?typeAdmin}}")
- .setParameter("typeDoctor", URI.create(Vocabulary.s_c_doctor))
- .setParameter("typeAdmin", URI.create(Vocabulary.s_c_administrator)).getSingleResult()
- ).intValue();
- } finally {
- em.close();
- }
+ return ((BigInteger) em.createNativeQuery(
+ "SELECT (count(?p) as ?investigatorCount) WHERE { ?p a ?typeDoctor . MINUS {?p a ?typeAdmin}}")
+ .setParameter("typeDoctor", URI.create(Vocabulary.s_c_doctor))
+ .setParameter("typeAdmin", URI.create(Vocabulary.s_c_administrator)).getSingleResult()
+ ).intValue();
}
}
diff --git a/src/main/java/cz/cvut/kbss/study/persistence/data/RemoteDataLoader.java b/src/main/java/cz/cvut/kbss/study/persistence/data/RemoteDataLoader.java
index 45995998..75ea8d2e 100644
--- a/src/main/java/cz/cvut/kbss/study/persistence/data/RemoteDataLoader.java
+++ b/src/main/java/cz/cvut/kbss/study/persistence/data/RemoteDataLoader.java
@@ -5,7 +5,6 @@
import cz.cvut.kbss.study.util.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
@@ -53,14 +52,14 @@ public String loadData(String remoteUrl, Map params) {
final URI urlWithQuery = Utils.prepareUri(remoteUrl, params);
final HttpEntity