From 2314c6e726a6941fde033d25161af6b3cb8efaf1 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Mon, 11 Apr 2016 16:09:36 +0200 Subject: [PATCH] #186 - Prepare upgrade to Spring Boot 1.4 M2 and Hibernate 5. Upgraded to Spring Boot 1.4 M2 and thus Hibernate 5.1 transitively. Switched to H2 as database for all examples using JPA by accident as the invalid error logging for HSQLDB schema creation got worse in 5.1 (see [0]). The JPA examples themselves have to stay on HSQLDB as H2 doesn't support stored procedures. The stored procedures example in turn has to be downgraded to 5.0.7 as all following versions currently break stored procedure execution support [1]. Reworked the JPA auditing example as 5.1 breaks on generic types used in support types like AbstractAuditable [2]. Tweaked content type assertions in some REST related test cases as Spring 4.3 returns an encoding alongside the media type. [0] https://hibernate.atlassian.net/browse/HHH-10605 [1] https://hibernate.atlassian.net/browse/HHH-10515 [2] https://hibernate.atlassian.net/browse/HHH-10514 --- .../jpa/eclipselink/Application.java | 21 +++++++-- .../jpa/auditing/AuditableUser.java | 44 ++++++++++--------- .../jpa/auditing/AuditableUserRepository.java | 6 +-- .../jpa/auditing/AuditingConfiguration.java | 37 ++-------------- .../src/main/resources/META-INF/orm.xml | 12 ----- .../jpa/auditing/AuditableUserSample.java | 14 +++--- jpa/example/src/test/resources/logback.xml | 16 ------- jpa/jpa21/pom.xml | 5 +++ pom.xml | 2 +- rest/headers/pom.xml | 4 +- rest/projections/pom.xml | 4 +- rest/security/pom.xml | 4 +- .../rest/security/UrlLevelSecurityTests.java | 22 +++++----- 13 files changed, 73 insertions(+), 118 deletions(-) delete mode 100644 jpa/example/src/main/resources/META-INF/orm.xml delete mode 100644 jpa/example/src/test/resources/logback.xml diff --git a/jpa/eclipselink/src/main/java/example/springdata/jpa/eclipselink/Application.java b/jpa/eclipselink/src/main/java/example/springdata/jpa/eclipselink/Application.java index 5b91feb7..018ee82d 100644 --- a/jpa/eclipselink/src/main/java/example/springdata/jpa/eclipselink/Application.java +++ b/jpa/eclipselink/src/main/java/example/springdata/jpa/eclipselink/Application.java @@ -18,11 +18,16 @@ package example.springdata.jpa.eclipselink; import java.util.Collections; import java.util.Map; +import javax.sql.DataSource; + +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration; +import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter; import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter; +import org.springframework.transaction.jta.JtaTransactionManager; /** * Spring Boot application that uses EclipseLink as the JPA provider. @@ -33,6 +38,16 @@ import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter; @SpringBootApplication public class Application extends JpaBaseConfiguration { + /** + * @param dataSource + * @param properties + * @param jtaTransactionManagerProvider + */ + protected Application(DataSource dataSource, JpaProperties properties, + ObjectProvider jtaTransactionManagerProvider) { + super(dataSource, properties, jtaTransactionManagerProvider); + } + /* * (non-Javadoc) * @see org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration#createJpaVendorAdapter() @@ -52,12 +67,12 @@ public class Application extends JpaBaseConfiguration { // Turn off dynamic weaving to disable LTW lookup in static weaving mode return Collections.singletonMap("eclipselink.weaving", "false"); } - + public static void main(String[] args) { - + CustomerRepository repository = SpringApplication.run(Application.class, args).getBean(CustomerRepository.class); repository.save(new Customer("Richard", "Feynman")); - + System.out.println(repository.findAll()); } } diff --git a/jpa/example/src/main/java/example/springdata/jpa/auditing/AuditableUser.java b/jpa/example/src/main/java/example/springdata/jpa/auditing/AuditableUser.java index d5461356..93086561 100644 --- a/jpa/example/src/main/java/example/springdata/jpa/auditing/AuditableUser.java +++ b/jpa/example/src/main/java/example/springdata/jpa/auditing/AuditableUser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,23 @@ */ package example.springdata.jpa.auditing; -import javax.persistence.Entity; +import lombok.Data; +import java.time.LocalDateTime; + +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.ManyToOne; + +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.domain.Auditable; import org.springframework.data.jpa.domain.AbstractAuditable; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; /** * User domain class that uses auditing functionality of Spring Data that can either be aquired implementing @@ -27,28 +40,17 @@ import org.springframework.data.jpa.domain.AbstractAuditable; * @author Oliver Gierke * @author Thomas Darimont */ +@Data @Entity -public class AuditableUser extends AbstractAuditable { - - private static final long serialVersionUID = 1L; +@EntityListeners(AuditingEntityListener.class) +public class AuditableUser { + private @Id @GeneratedValue Long id; private String username; - /** - * Set's the user's name. - * - * @param username the username to set - */ - public void setUsername(String username) { - this.username = username; - } + private @CreatedDate LocalDateTime createdDate; + private @LastModifiedDate LocalDateTime lastModifiedDate; - /** - * Returns the user's name. - * - * @return the username - */ - public String getUsername() { - return username; - } + private @ManyToOne @CreatedBy AuditableUser createdBy; + private @ManyToOne @LastModifiedBy AuditableUser lastModifiedBy; } diff --git a/jpa/example/src/main/java/example/springdata/jpa/auditing/AuditableUserRepository.java b/jpa/example/src/main/java/example/springdata/jpa/auditing/AuditableUserRepository.java index 1c4e3220..2595c42a 100644 --- a/jpa/example/src/main/java/example/springdata/jpa/auditing/AuditableUserRepository.java +++ b/jpa/example/src/main/java/example/springdata/jpa/auditing/AuditableUserRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,4 @@ import org.springframework.data.repository.CrudRepository; /** * @author Oliver Gierke */ -public interface AuditableUserRepository extends CrudRepository { - -} +public interface AuditableUserRepository extends CrudRepository {} diff --git a/jpa/example/src/main/java/example/springdata/jpa/auditing/AuditingConfiguration.java b/jpa/example/src/main/java/example/springdata/jpa/auditing/AuditingConfiguration.java index 905c457f..26e6470f 100644 --- a/jpa/example/src/main/java/example/springdata/jpa/auditing/AuditingConfiguration.java +++ b/jpa/example/src/main/java/example/springdata/jpa/auditing/AuditingConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,48 +15,17 @@ */ package example.springdata.jpa.auditing; -import javax.sql.DataSource; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.vendor.Database; -import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; /** * @author Oliver Gierke */ -@Configuration -@EnableAutoConfiguration +@SpringBootApplication @EnableJpaAuditing class AuditingConfiguration { - /** - * We need to configure a {@link LocalContainerEntityManagerFactoryBean} manually here as Spring does not - * automatically add the {@code orm.xml} if a {@code persistence.xml} is located right beside it. This is - * necessary to get the {@link example.springdata.jpa.basics.BasicFactorySetup} sample working. However, in a {code - * persistence.xml}-less codebase you can rely on Spring Boot on setting the correct defaults. - * - * @return - */ - @Bean - LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) { - - HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter(); - adapter.setDatabase(Database.HSQL); - adapter.setGenerateDdl(true); - - LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean(); - factoryBean.setPackagesToScan(getClass().getPackage().getName()); - factoryBean.setMappingResources("META-INF/orm.xml"); - factoryBean.setJpaVendorAdapter(adapter); - factoryBean.setDataSource(dataSource); - - return factoryBean; - } - @Bean AuditorAwareImpl auditorAware() { return new AuditorAwareImpl(); diff --git a/jpa/example/src/main/resources/META-INF/orm.xml b/jpa/example/src/main/resources/META-INF/orm.xml deleted file mode 100644 index da5ba62b..00000000 --- a/jpa/example/src/main/resources/META-INF/orm.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/jpa/example/src/test/java/example/springdata/jpa/auditing/AuditableUserSample.java b/jpa/example/src/test/java/example/springdata/jpa/auditing/AuditableUserSample.java index c9eea143..c4f67566 100644 --- a/jpa/example/src/test/java/example/springdata/jpa/auditing/AuditableUserSample.java +++ b/jpa/example/src/test/java/example/springdata/jpa/auditing/AuditableUserSample.java @@ -21,24 +21,20 @@ import static org.junit.Assert.*; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.jpa.domain.support.AuditingEntityListener; -import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.transaction.annotation.Transactional; -import example.springdata.jpa.auditing.AuditableUser; -import example.springdata.jpa.auditing.AuditableUserRepository; -import example.springdata.jpa.auditing.AuditingConfiguration; -import example.springdata.jpa.auditing.AuditorAwareImpl; - /** * @author Oliver Gierke * @author Thomas Darimont */ + @RunWith(SpringJUnit4ClassRunner.class) @Transactional -@ContextConfiguration(classes = AuditingConfiguration.class) +@SpringBootTest(classes = AuditingConfiguration.class) public class AuditableUserSample { @Autowired AuditableUserRepository repository; @@ -58,7 +54,7 @@ public class AuditableUserSample { user = repository.save(user); user = repository.save(user); - assertEquals(user, user.getCreatedBy()); - assertEquals(user, user.getLastModifiedBy()); + assertThat(user.getCreatedBy(), is(user)); + assertThat(user.getLastModifiedBy(), is(user)); } } diff --git a/jpa/example/src/test/resources/logback.xml b/jpa/example/src/test/resources/logback.xml deleted file mode 100644 index 40a8f339..00000000 --- a/jpa/example/src/test/resources/logback.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - %d %5p %40.40c:%4L - %m%n - - - - - - - - - - \ No newline at end of file diff --git a/jpa/jpa21/pom.xml b/jpa/jpa21/pom.xml index d4052f54..b9d785aa 100644 --- a/jpa/jpa21/pom.xml +++ b/jpa/jpa21/pom.xml @@ -11,4 +11,9 @@ spring-data-jpa-jpa21 Spring Data JPA - JPA 2.1 specific features + + + 5.0.7.Final + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 747565e5..0129ba92 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ org.springframework.boot spring-boot-starter-parent - 1.4.0.M1 + 1.4.0.M2 diff --git a/rest/headers/pom.xml b/rest/headers/pom.xml index 9be7b2ed..fb42a018 100644 --- a/rest/headers/pom.xml +++ b/rest/headers/pom.xml @@ -25,8 +25,8 @@ - org.hsqldb - hsqldb + com.h2database + h2 diff --git a/rest/projections/pom.xml b/rest/projections/pom.xml index 80ac096b..cb4949fd 100644 --- a/rest/projections/pom.xml +++ b/rest/projections/pom.xml @@ -20,8 +20,8 @@ - org.hsqldb - hsqldb + com.h2database + h2 diff --git a/rest/security/pom.xml b/rest/security/pom.xml index 88a21f5d..dcc15649 100644 --- a/rest/security/pom.xml +++ b/rest/security/pom.xml @@ -29,8 +29,8 @@ - org.hsqldb - hsqldb + com.h2database + h2 diff --git a/rest/security/src/test/java/example/springdata/rest/security/UrlLevelSecurityTests.java b/rest/security/src/test/java/example/springdata/rest/security/UrlLevelSecurityTests.java index 69c1978d..3e3daa0c 100644 --- a/rest/security/src/test/java/example/springdata/rest/security/UrlLevelSecurityTests.java +++ b/rest/security/src/test/java/example/springdata/rest/security/UrlLevelSecurityTests.java @@ -22,10 +22,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultHandlers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*; -import example.springdata.rest.security.Application; -import example.springdata.rest.security.Employee; -import example.springdata.rest.security.SecurityConfiguration; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -75,7 +71,7 @@ public class UrlLevelSecurityTests { mvc.perform(get("/").// accept(MediaTypes.HAL_JSON)).// - andExpect(header().string("Content-Type", MediaTypes.HAL_JSON.toString())).// + andExpect(content().contentTypeCompatibleWith(MediaTypes.HAL_JSON)).// andExpect(status().isOk()).// andDo(print()); } @@ -94,12 +90,12 @@ public class UrlLevelSecurityTests { public void allowsGetRequestsButRejectsPostForUser() throws Exception { HttpHeaders headers = new HttpHeaders(); - headers.add(HttpHeaders.ACCEPT, MediaTypes.HAL_JSON.toString()); + headers.add(HttpHeaders.ACCEPT, MediaTypes.HAL_JSON_VALUE); headers.add(HttpHeaders.AUTHORIZATION, "Basic " + new String(Base64.encode(("greg:turnquist").getBytes()))); mvc.perform(get("/employees").// headers(headers)).// - andExpect(content().contentType(MediaTypes.HAL_JSON)).// + andExpect(content().contentTypeCompatibleWith(MediaTypes.HAL_JSON)).// andExpect(status().isOk()).// andDo(print()); @@ -113,20 +109,22 @@ public class UrlLevelSecurityTests { public void allowsPostRequestForAdmin() throws Exception { HttpHeaders headers = new HttpHeaders(); - headers.set(HttpHeaders.ACCEPT, "application/hal+json"); + headers.set(HttpHeaders.ACCEPT, MediaTypes.HAL_JSON_VALUE); headers.set(HttpHeaders.AUTHORIZATION, "Basic " + new String(Base64.encode(("ollie:gierke").getBytes()))); mvc.perform(get("/employees").// headers(headers)).// - andExpect(content().contentType(MediaTypes.HAL_JSON)).// + andExpect(content().contentTypeCompatibleWith(MediaTypes.HAL_JSON)).// andExpect(status().isOk()).// andDo(print()); headers.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); - String location = mvc.perform(post("/employees").// - content(PAYLOAD).// - headers(headers)).// + String location = mvc + .perform(post("/employees").// + content(PAYLOAD).// + headers(headers)) + .// andExpect(status().isCreated()).// andDo(print()).// andReturn().getResponse().getHeader(HttpHeaders.LOCATION);