#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
This commit is contained in:
@@ -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<JtaTransactionManager> 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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<AuditableUser, Long> {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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<AuditableUser, Long> {
|
||||
|
||||
}
|
||||
public interface AuditableUserRepository extends CrudRepository<AuditableUser, Long> {}
|
||||
|
||||
@@ -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 <em>not</em>
|
||||
* automatically add the {@code orm.xml} <em>if</em> 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();
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd" version="2.0">
|
||||
|
||||
<persistence-unit-metadata>
|
||||
<persistence-unit-defaults>
|
||||
<entity-listeners>
|
||||
<entity-listener class="org.springframework.data.jpa.domain.support.AuditingEntityListener" />
|
||||
</entity-listeners>
|
||||
</persistence-unit-defaults>
|
||||
</persistence-unit-metadata>
|
||||
|
||||
</entity-mappings>
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d %5p %40.40c:%4L - %m%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework" level="error" />
|
||||
|
||||
<root level="error">
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
@@ -11,4 +11,9 @@
|
||||
<artifactId>spring-data-jpa-jpa21</artifactId>
|
||||
<name>Spring Data JPA - JPA 2.1 specific features</name>
|
||||
|
||||
<properties>
|
||||
<!-- Last Hibernate 5.x version that doesn't break stored procedure support on HSQLDB -->
|
||||
<hibernate.version>5.0.7.Final</hibernate.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
2
pom.xml
2
pom.xml
@@ -12,7 +12,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.4.0.M1</version>
|
||||
<version>1.4.0.M2</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user