Sync the javaconfig branch with the master

This commit is contained in:
Antoine Rey 2015-08-21 18:23:14 +02:00
commit b0c1d7a0ec
18 changed files with 229 additions and 209 deletions

139
pom.xml
View file

@ -11,50 +11,24 @@
<properties> <properties>
<!-- Generic properties --> <!-- Generic properties -->
<java.version>1.8</java.version> <java.version>1.7</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- Spring --> <!-- Spring -->
<spring-framework.version>4.1.6.RELEASE</spring-framework.version> <spring-io-platform.version>1.1.3.RELEASE</spring-io-platform.version>
<spring-data-jpa.version>1.8.0.RELEASE</spring-data-jpa.version> <spring-data-jdbc.version>1.1.0.RELEASE</spring-data-jdbc.version>
<!-- Java EE / Java SE dependencies --> <!-- Java EE / Java SE dependencies -->
<jsp.version>2.2</jsp.version> <tomcat.version>7.0.59</tomcat.version>
<jstl.version>1.2</jstl.version>
<tomcat.servlet.version>7.0.47</tomcat.servlet.version>
<jaxb-impl.version>2.2.7</jaxb-impl.version>
<!-- Hibernate / JPA -->
<hibernate.version>4.3.8.Final</hibernate.version>
<!-- Bean validation -->
<hibernate-validator.version>4.3.1.Final</hibernate-validator.version>
<!-- Database access -->
<tomcat-jdbc.version>7.0.42</tomcat-jdbc.version>
<ehcache.version>2.6.10</ehcache.version>
<hsqldb.version>2.3.2</hsqldb.version>
<!-- AOP -->
<aspectj.version>1.8.5</aspectj.version>
<!-- Logging -->
<logback.version>1.1.3</logback.version>
<slf4j.version>1.7.12</slf4j.version>
<!-- JSon-->
<json-path.version>2.0.0</json-path.version>
<!-- Test --> <!-- Test -->
<junit.version>4.12</junit.version> <assertj.version>2.1.0</assertj.version>
<assertj.version>3.0.0</assertj.version>
<!-- Dates --> <!-- Dates -->
<jodatime-hibernate.version>1.3</jodatime-hibernate.version> <jodatime-hibernate.version>1.3</jodatime-hibernate.version>
<jodatime-jsptags.version>1.1.1</jodatime-jsptags.version> <jodatime-jsptags.version>1.1.1</jodatime-jsptags.version>
<jodatime.version>2.7</jodatime.version>
<jadira-usertype-core.version>3.2.0.GA</jadira-usertype-core.version> <jadira-usertype-core.version>3.2.0.GA</jadira-usertype-core.version>
@ -62,14 +36,25 @@
<webjars-bootstrap.version>2.3.0</webjars-bootstrap.version> <webjars-bootstrap.version>2.3.0</webjars-bootstrap.version>
<webjars-jquery-ui.version>1.10.3</webjars-jquery-ui.version> <webjars-jquery-ui.version>1.10.3</webjars-jquery-ui.version>
<webjars-jquery.version>2.0.3-1</webjars-jquery.version> <webjars-jquery.version>2.0.3-1</webjars-jquery.version>
<dandelion.version>0.10.1</dandelion.version> <dandelion.version>1.0.1</dandelion.version>
<mysql.version>5.1.22</mysql.version>
<cobertura.version>2.7</cobertura.version> <cobertura.version>2.7</cobertura.version>
</properties> </properties>
<dependencyManagement>
<!-- Import the maven Spring IO Platform Bill Of Materials (BOM) -->
<dependencies>
<dependency>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>${spring-io-platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.jadira.usertype</groupId> <groupId>org.jadira.usertype</groupId>
@ -79,45 +64,49 @@
<dependency> <dependency>
<groupId>org.apache.tomcat</groupId> <groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId> <artifactId>tomcat-servlet-api</artifactId>
<version>${tomcat.servlet.version}</version> <version>${tomcat.version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.servlet.jsp</groupId> <groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId> <artifactId>javax.servlet.jsp-api</artifactId>
<version>2.1</version> <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper-el</artifactId>
<version>${tomcat.version}</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.glassfish.web</groupId> <groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-impl</artifactId> <artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.sun.xml.bind</groupId> <groupId>org.apache.taglibs</groupId>
<artifactId>jaxb-impl</artifactId> <artifactId>taglibs-standard-jstlel</artifactId>
<version>${jaxb-impl.version}</version>
<scope>provided</scope>
</dependency> </dependency>
<!-- JSon --> <!-- JSon -->
<dependency> <dependency>
<groupId>com.jayway.jsonpath</groupId> <groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId> <artifactId>json-path</artifactId>
<version>${json-path.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- SPRING, SPRING, SPRINGITY SPRING --> <!-- SPRING, SPRING, SPRINGITY SPRING -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId> <artifactId>spring-data-jdbc-core</artifactId>
<version>${spring-data-jpa.version}</version> <version>${spring-data-jdbc.version}</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
@ -130,55 +119,28 @@
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId> <artifactId>spring-jdbc</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring-framework.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId> <artifactId>spring-webmvc</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring-framework.version}</version>
</dependency> </dependency>
<!-- used for EhCacheCacheManager --> <!-- used for EhCacheCacheManager -->
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId> <artifactId>spring-context-support</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring-framework.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId> <artifactId>spring-oxm</artifactId>
<version>${spring-framework.version}</version>
<exclusions>
<exclusion>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.aspectj</groupId> <groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId> <artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.aspectj</groupId> <groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId> <artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
@ -189,20 +151,16 @@
<dependency> <dependency>
<groupId>org.apache.tomcat</groupId> <groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId> <artifactId>tomcat-jdbc</artifactId>
<version>${tomcat-jdbc.version}</version>
</dependency> </dependency>
<!-- Logging with SLF4J & LogBack --> <!-- Logging with SLF4J & LogBack -->
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
<scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>ch.qos.logback</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId> <artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
@ -210,7 +168,6 @@
<dependency> <dependency>
<groupId>joda-time</groupId> <groupId>joda-time</groupId>
<artifactId>joda-time</artifactId> <artifactId>joda-time</artifactId>
<version>${jodatime.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>joda-time</groupId> <groupId>joda-time</groupId>
@ -224,37 +181,31 @@
</dependency> </dependency>
<!-- Databases - Uses HSQL by default --> <!-- Databases - Uses HSQL by default -->
<!-- <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> -->
<dependency> <dependency>
<groupId>org.hsqldb</groupId> <groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId> <artifactId>hsqldb</artifactId>
<version>${hsqldb.version}</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<!-- For MySql only --> <!-- For MySql only -->
<!-- <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> --> <!-- <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> -->
<!-- HIBERNATE --> <!-- HIBERNATE -->
<dependency> <dependency>
<groupId>org.hibernate</groupId> <groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId> <artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.hibernate</groupId> <groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId> <artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.hibernate</groupId> <groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId> <artifactId>hibernate-ehcache</artifactId>
<version>${hibernate.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.sf.ehcache</groupId> <groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId> <artifactId>ehcache-core</artifactId>
<version>${ehcache.version}</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>commons-logging</groupId> <groupId>commons-logging</groupId>
@ -283,19 +234,18 @@
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId> <artifactId>spring-test</artifactId>
<version>${spring-framework.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.assertj</groupId> <groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId> <artifactId>assertj-core</artifactId>
<version>${assertj.version}</version> <version>${assertj.version}</version>
<scope>test</scope>
</dependency> </dependency>
<!-- Dandelion --> <!-- Dandelion -->
@ -432,6 +382,7 @@
<formats> <formats>
<format>html</format> <format>html</format>
</formats> </formats>
<check/>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>

View file

@ -91,13 +91,13 @@ public class Owner extends Person {
protected Set<Pet> getPetsInternal() { protected Set<Pet> getPetsInternal() {
if (this.pets == null) { if (this.pets == null) {
this.pets = new HashSet<Pet>(); this.pets = new HashSet<>();
} }
return this.pets; return this.pets;
} }
public List<Pet> getPets() { public List<Pet> getPets() {
List<Pet> sortedPets = new ArrayList<Pet>(getPetsInternal()); List<Pet> sortedPets = new ArrayList<>(getPetsInternal());
PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true)); PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true));
return Collections.unmodifiableList(sortedPets); return Collections.unmodifiableList(sortedPets);
} }

View file

@ -94,13 +94,13 @@ public class Pet extends NamedEntity {
protected Set<Visit> getVisitsInternal() { protected Set<Visit> getVisitsInternal() {
if (this.visits == null) { if (this.visits == null) {
this.visits = new HashSet<Visit>(); this.visits = new HashSet<>();
} }
return this.visits; return this.visits;
} }
public List<Visit> getVisits() { public List<Visit> getVisits() {
List<Visit> sortedVisits = new ArrayList<Visit>(getVisitsInternal()); List<Visit> sortedVisits = new ArrayList<>(getVisitsInternal());
PropertyComparator.sort(sortedVisits, new MutableSortDefinition("date", false, false)); PropertyComparator.sort(sortedVisits, new MutableSortDefinition("date", false, false));
return Collections.unmodifiableList(sortedVisits); return Collections.unmodifiableList(sortedVisits);
} }

View file

@ -56,14 +56,14 @@ public class Vet extends Person {
protected Set<Specialty> getSpecialtiesInternal() { protected Set<Specialty> getSpecialtiesInternal() {
if (this.specialties == null) { if (this.specialties == null) {
this.specialties = new HashSet<Specialty>(); this.specialties = new HashSet<>();
} }
return this.specialties; return this.specialties;
} }
@XmlElement @XmlElement
public List<Specialty> getSpecialties() { public List<Specialty> getSpecialties() {
List<Specialty> sortedSpecs = new ArrayList<Specialty>(getSpecialtiesInternal()); List<Specialty> sortedSpecs = new ArrayList<>(getSpecialtiesInternal());
PropertyComparator.sort(sortedSpecs, new MutableSortDefinition("name", true, true)); PropertyComparator.sort(sortedSpecs, new MutableSortDefinition("name", true, true));
return Collections.unmodifiableList(sortedSpecs); return Collections.unmodifiableList(sortedSpecs);
} }

View file

@ -36,7 +36,7 @@ public class Vets {
@XmlElement @XmlElement
public List<Vet> getVetList() { public List<Vet> getVetList() {
if (vets == null) { if (vets == null) {
vets = new ArrayList<Vet>(); vets = new ArrayList<>();
} }
return vets; return vets;
} }

View file

@ -35,8 +35,6 @@ import org.springframework.samples.petclinic.model.Pet;
import org.springframework.samples.petclinic.model.PetType; import org.springframework.samples.petclinic.model.PetType;
import org.springframework.samples.petclinic.model.Visit; import org.springframework.samples.petclinic.model.Visit;
import org.springframework.samples.petclinic.repository.OwnerRepository; import org.springframework.samples.petclinic.repository.OwnerRepository;
import org.springframework.samples.petclinic.repository.VisitRepository;
import org.springframework.samples.petclinic.util.EntityUtils;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
/** /**
@ -52,15 +50,12 @@ import org.springframework.stereotype.Repository;
@Repository @Repository
public class JdbcOwnerRepositoryImpl implements OwnerRepository { public class JdbcOwnerRepositoryImpl implements OwnerRepository {
private VisitRepository visitRepository;
private NamedParameterJdbcTemplate namedParameterJdbcTemplate; private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
private SimpleJdbcInsert insertOwner; private SimpleJdbcInsert insertOwner;
@Autowired @Autowired
public JdbcOwnerRepositoryImpl(DataSource dataSource, NamedParameterJdbcTemplate namedParameterJdbcTemplate, public JdbcOwnerRepositoryImpl(DataSource dataSource, NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
VisitRepository visitRepository) {
this.insertOwner = new SimpleJdbcInsert(dataSource) this.insertOwner = new SimpleJdbcInsert(dataSource)
.withTableName("owners") .withTableName("owners")
@ -68,7 +63,6 @@ public class JdbcOwnerRepositoryImpl implements OwnerRepository {
this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
this.visitRepository = visitRepository;
} }
@ -79,7 +73,7 @@ public class JdbcOwnerRepositoryImpl implements OwnerRepository {
*/ */
@Override @Override
public Collection<Owner> findByLastName(String lastName) throws DataAccessException { public Collection<Owner> findByLastName(String lastName) throws DataAccessException {
Map<String, Object> params = new HashMap<String, Object>(); Map<String, Object> params = new HashMap<>();
params.put("lastName", lastName + "%"); params.put("lastName", lastName + "%");
List<Owner> owners = this.namedParameterJdbcTemplate.query( List<Owner> owners = this.namedParameterJdbcTemplate.query(
"SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE last_name like :lastName", "SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE last_name like :lastName",
@ -98,7 +92,7 @@ public class JdbcOwnerRepositoryImpl implements OwnerRepository {
public Owner findById(int id) throws DataAccessException { public Owner findById(int id) throws DataAccessException {
Owner owner; Owner owner;
try { try {
Map<String, Object> params = new HashMap<String, Object>(); Map<String, Object> params = new HashMap<>();
params.put("id", id); params.put("id", id);
owner = this.namedParameterJdbcTemplate.queryForObject( owner = this.namedParameterJdbcTemplate.queryForObject(
"SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE id= :id", "SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE id= :id",
@ -113,21 +107,15 @@ public class JdbcOwnerRepositoryImpl implements OwnerRepository {
} }
public void loadPetsAndVisits(final Owner owner) { public void loadPetsAndVisits(final Owner owner) {
Map<String, Object> params = new HashMap<String, Object>(); Map<String, Object> params = new HashMap<>();
params.put("id", owner.getId().intValue()); params.put("id", owner.getId());
final List<JdbcPet> pets = this.namedParameterJdbcTemplate.query( final List<JdbcPet> pets = this.namedParameterJdbcTemplate.query(
"SELECT id, name, birth_date, type_id, owner_id FROM pets WHERE owner_id=:id", "SELECT pets.id, name, birth_date, type_id, owner_id, visits.id as visit_id, visit_date, description, pet_id FROM pets LEFT OUTER JOIN visits ON pets.id = pet_id WHERE owner_id=:id",
params, params,
new JdbcPetRowMapper() new JdbcPetVisitExtractor()
); );
for (JdbcPet pet : pets) { for (JdbcPet pet : pets) {
owner.addPet(pet); owner.addPet(pet);
// Pet types have not been loaded at this stage. They are loaded separately
pet.setType(EntityUtils.getById(getPetTypes(), PetType.class, pet.getTypeId()));
List<Visit> visits = this.visitRepository.findByPetId(pet.getId());
for (Visit visit : visits) {
pet.addVisit(visit);
}
} }
} }

View file

@ -73,7 +73,7 @@ public class JdbcPetRepositoryImpl implements PetRepository {
@Override @Override
public List<PetType> findPetTypes() throws DataAccessException { public List<PetType> findPetTypes() throws DataAccessException {
Map<String, Object> params = new HashMap<String, Object>(); Map<String, Object> params = new HashMap<>();
return this.namedParameterJdbcTemplate.query( return this.namedParameterJdbcTemplate.query(
"SELECT id, name FROM types ORDER BY name", "SELECT id, name FROM types ORDER BY name",
params, params,
@ -84,14 +84,14 @@ public class JdbcPetRepositoryImpl implements PetRepository {
public Pet findById(int id) throws DataAccessException { public Pet findById(int id) throws DataAccessException {
JdbcPet pet; JdbcPet pet;
try { try {
Map<String, Object> params = new HashMap<String, Object>(); Map<String, Object> params = new HashMap<>();
params.put("id", id); params.put("id", id);
pet = this.namedParameterJdbcTemplate.queryForObject( pet = this.namedParameterJdbcTemplate.queryForObject(
"SELECT id, name, birth_date, type_id, owner_id FROM pets WHERE id=:id", "SELECT id, name, birth_date, type_id, owner_id FROM pets WHERE id=:id",
params, params,
new JdbcPetRowMapper()); new JdbcPetRowMapper());
} catch (EmptyResultDataAccessException ex) { } catch (EmptyResultDataAccessException ex) {
throw new ObjectRetrievalFailureException(Pet.class, new Integer(id)); throw new ObjectRetrievalFailureException(Pet.class, id);
} }
Owner owner = this.ownerRepository.findById(pet.getOwnerId()); Owner owner = this.ownerRepository.findById(pet.getOwnerId());
owner.addPet(pet); owner.addPet(pet);

View file

@ -20,18 +20,18 @@ import java.sql.SQLException;
import java.util.Date; import java.util.Date;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.RowMapper;
/** /**
* {@link BeanPropertyRowMapper} implementation mapping data from a {@link ResultSet} to the corresponding properties * {@link RowMapper} implementation mapping data from a {@link ResultSet} to the corresponding properties
* of the {@link JdbcPet} class. * of the {@link JdbcPet} class.
*/ */
class JdbcPetRowMapper extends BeanPropertyRowMapper<JdbcPet> { class JdbcPetRowMapper implements RowMapper<JdbcPet> {
@Override @Override
public JdbcPet mapRow(ResultSet rs, int rownum) throws SQLException { public JdbcPet mapRow(ResultSet rs, int rownum) throws SQLException {
JdbcPet pet = new JdbcPet(); JdbcPet pet = new JdbcPet();
pet.setId(rs.getInt("id")); pet.setId(rs.getInt("pets.id"));
pet.setName(rs.getString("name")); pet.setName(rs.getString("name"));
Date birthDate = rs.getDate("birth_date"); Date birthDate = rs.getDate("birth_date");
pet.setBirthDate(new DateTime(birthDate)); pet.setBirthDate(new DateTime(birthDate));

View file

@ -0,0 +1,54 @@
/*
* Copyright 2002-2015 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.jdbc;
import org.springframework.data.jdbc.core.OneToManyResultSetExtractor;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.samples.petclinic.model.Visit;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* {@link ResultSetExtractor} implementation by using the
* {@link OneToManyResultSetExtractor} of Spring Data Core JDBC Extensions.
*/
public class JdbcPetVisitExtractor extends
OneToManyResultSetExtractor<JdbcPet, Visit, Integer> {
public JdbcPetVisitExtractor() {
super(new JdbcPetRowMapper(), new JdbcVisitRowMapper());
}
@Override
protected Integer mapPrimaryKey(ResultSet rs) throws SQLException {
return rs.getInt("pets.id");
}
@Override
protected Integer mapForeignKey(ResultSet rs) throws SQLException {
if (rs.getObject("visits.pet_id") == null) {
return null;
} else {
return rs.getInt("visits.pet_id");
}
}
@Override
protected void addChild(JdbcPet root, Visit child) {
root.addVisit(child);
}
}

View file

@ -32,8 +32,7 @@ import org.springframework.samples.petclinic.util.EntityUtils;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
/** /**
* A simple JDBC-based implementation of the {@link VetRepository} interface. Uses @Cacheable to cache the result of the * A simple JDBC-based implementation of the {@link VetRepository} interface.
* {@link findAll} method
* *
* @author Ken Krebs * @author Ken Krebs
* @author Juergen Hoeller * @author Juergen Hoeller
@ -55,12 +54,10 @@ public class JdbcVetRepositoryImpl implements VetRepository {
/** /**
* Refresh the cache of Vets that the ClinicService is holding. * Refresh the cache of Vets that the ClinicService is holding.
*
* @see org.springframework.samples.petclinic.model.service.ClinicService#shouldFindVets()
*/ */
@Override @Override
public Collection<Vet> findAll() throws DataAccessException { public Collection<Vet> findAll() throws DataAccessException {
List<Vet> vets = new ArrayList<Vet>(); List<Vet> vets = new ArrayList<>();
// Retrieve the list of all vets. // Retrieve the list of all vets.
vets.addAll(this.jdbcTemplate.query( vets.addAll(this.jdbcTemplate.query(
"SELECT id, first_name, last_name FROM vets ORDER BY last_name,first_name", "SELECT id, first_name, last_name FROM vets ORDER BY last_name,first_name",
@ -78,10 +75,10 @@ public class JdbcVetRepositoryImpl implements VetRepository {
new BeanPropertyRowMapper<Integer>() { new BeanPropertyRowMapper<Integer>() {
@Override @Override
public Integer mapRow(ResultSet rs, int row) throws SQLException { public Integer mapRow(ResultSet rs, int row) throws SQLException {
return Integer.valueOf(rs.getInt(1)); return rs.getInt(1);
} }
}, },
vet.getId().intValue()); vet.getId());
for (int specialtyId : vetSpecialtiesIds) { for (int specialtyId : vetSpecialtiesIds) {
Specialty specialty = EntityUtils.getById(specialties, Specialty.class, specialtyId); Specialty specialty = EntityUtils.getById(specialties, Specialty.class, specialtyId);
vet.addSpecialty(specialty); vet.addSpecialty(specialty);

View file

@ -15,17 +15,8 @@
*/ */
package org.springframework.samples.petclinic.repository.jdbc; package org.springframework.samples.petclinic.repository.jdbc;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import javax.sql.DataSource;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert; import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
@ -33,6 +24,9 @@ import org.springframework.samples.petclinic.model.Visit;
import org.springframework.samples.petclinic.repository.VisitRepository; import org.springframework.samples.petclinic.repository.VisitRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import javax.sql.DataSource;
import java.util.List;
/** /**
* A simple JDBC-based implementation of the {@link VisitRepository} interface. * A simple JDBC-based implementation of the {@link VisitRepository} interface.
* *
@ -72,10 +66,6 @@ public class JdbcVisitRepositoryImpl implements VisitRepository {
} }
} }
public void deletePet(int id) throws DataAccessException {
this.jdbcTemplate.update("DELETE FROM pets WHERE id=?", id);
}
/** /**
* Creates a {@link MapSqlParameterSource} based on data values from the supplied {@link Visit} instance. * Creates a {@link MapSqlParameterSource} based on data values from the supplied {@link Visit} instance.
@ -90,21 +80,9 @@ public class JdbcVisitRepositoryImpl implements VisitRepository {
@Override @Override
public List<Visit> findByPetId(Integer petId) { public List<Visit> findByPetId(Integer petId) {
final List<Visit> visits = this.jdbcTemplate.query( return this.jdbcTemplate.query(
"SELECT id, visit_date, description FROM visits WHERE pet_id=?", "SELECT id as visit_id, visit_date, description FROM visits WHERE pet_id=?",
new BeanPropertyRowMapper<Visit>() { new JdbcVisitRowMapper(), petId);
@Override
public Visit mapRow(ResultSet rs, int row) throws SQLException {
Visit visit = new Visit();
visit.setId(rs.getInt("id"));
Date visitDate = rs.getDate("visit_date");
visit.setDate(new DateTime(visitDate));
visit.setDescription(rs.getString("description"));
return visit;
}
},
petId);
return visits;
} }
} }

View file

@ -0,0 +1,42 @@
/*
* Copyright 2002-2015 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.samples.petclinic.repository.jdbc;
import org.joda.time.DateTime;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.samples.petclinic.model.Visit;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
/**
* {@link RowMapper} implementation mapping data from a {@link ResultSet} to the corresponding properties
* of the {@link Visit} class.
*/
class JdbcVisitRowMapper implements RowMapper<Visit> {
@Override
public Visit mapRow(ResultSet rs, int row) throws SQLException {
Visit visit = new Visit();
visit.setId(rs.getInt("visit_id"));
Date visitDate = rs.getDate("visit_date");
visit.setDate(new DateTime(visitDate));
visit.setDescription(rs.getString("description"));
return visit;
}
}

View file

@ -45,7 +45,7 @@ public abstract class EntityUtils {
public static <T extends BaseEntity> T getById(Collection<T> entities, Class<T> entityClass, int entityId) public static <T extends BaseEntity> T getById(Collection<T> entities, Class<T> entityClass, int entityId)
throws ObjectRetrievalFailureException { throws ObjectRetrievalFailureException {
for (T entity : entities) { for (T entity : entities) {
if (entity.getId().intValue() == entityId && entityClass.isInstance(entity)) { if (entity.getId() == entityId && entityClass.isInstance(entity)) {
return entity; return entity;
} }
} }

View file

@ -34,6 +34,8 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus; import org.springframework.web.bind.support.SessionStatus;
import javax.validation.Valid;
/** /**
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Ken Krebs * @author Ken Krebs
@ -57,8 +59,9 @@ public class PetController {
} }
@InitBinder @InitBinder
public void setAllowedFields(WebDataBinder dataBinder) { public void initBinder(WebDataBinder dataBinder) {
dataBinder.setDisallowedFields("id"); dataBinder.setDisallowedFields("id");
dataBinder.setValidator(new PetValidator());
} }
@RequestMapping(value = "/owners/{ownerId}/pets/new", method = RequestMethod.GET) @RequestMapping(value = "/owners/{ownerId}/pets/new", method = RequestMethod.GET)
@ -71,8 +74,7 @@ public class PetController {
} }
@RequestMapping(value = "/owners/{ownerId}/pets/new", method = RequestMethod.POST) @RequestMapping(value = "/owners/{ownerId}/pets/new", method = RequestMethod.POST)
public String processCreationForm(@ModelAttribute("pet") Pet pet, BindingResult result, SessionStatus status) { public String processCreationForm(@Valid Pet pet, BindingResult result, SessionStatus status) {
new PetValidator().validate(pet, result);
if (result.hasErrors()) { if (result.hasErrors()) {
return "pets/createOrUpdatePetForm"; return "pets/createOrUpdatePetForm";
} else { } else {
@ -90,9 +92,7 @@ public class PetController {
} }
@RequestMapping(value = "/owners/{ownerId}/pets/{petId}/edit", method = {RequestMethod.PUT, RequestMethod.POST}) @RequestMapping(value = "/owners/{ownerId}/pets/{petId}/edit", method = {RequestMethod.PUT, RequestMethod.POST})
public String processUpdateForm(@ModelAttribute("pet") Pet pet, BindingResult result, SessionStatus status) { public String processUpdateForm(@Valid Pet pet, BindingResult result, SessionStatus status) {
// we're not using @Valid annotation here because it is easier to define such validation rule in Java
new PetValidator().validate(pet, result);
if (result.hasErrors()) { if (result.hasErrors()) {
return "pets/createOrUpdatePetForm"; return "pets/createOrUpdatePetForm";
} else { } else {

View file

@ -18,16 +18,22 @@ package org.springframework.samples.petclinic.web;
import org.springframework.samples.petclinic.model.Pet; import org.springframework.samples.petclinic.model.Pet;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.validation.Errors; import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
/** /**
* <code>Validator</code> for <code>Pet</code> forms. * <code>Validator</code> for <code>Pet</code> forms.
* <p>
* We're not using Bean Validation annotations here because it is easier to define such validation rule in Java.
* </p>
* *
* @author Ken Krebs * @author Ken Krebs
* @author Juergen Hoeller * @author Juergen Hoeller
*/ */
public class PetValidator { public class PetValidator implements Validator {
public void validate(Pet pet, Errors errors) { @Override
public void validate(Object obj, Errors errors) {
Pet pet = (Pet) obj;
String name = pet.getName(); String name = pet.getName();
// name validation // name validation
if (!StringUtils.hasLength(name)) { if (!StringUtils.hasLength(name)) {
@ -47,4 +53,13 @@ public class PetValidator {
} }
} }
/**
* This Validator validates *just* Pet instances
*/
@Override
public boolean supports(Class<?> clazz) {
return Pet.class.equals(clazz);
}
} }

View file

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="ISO-8859-1"?> <?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="2.5"> version="3.0" metadata-complete="true">
<display-name>Spring PetClinic</display-name> <display-name>Spring PetClinic</display-name>
<description>Spring PetClinic sample application</description> <description>Spring PetClinic sample application</description>
@ -78,6 +78,25 @@ http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
<url-pattern>/dandelion-assets/*</url-pattern> <url-pattern>/dandelion-assets/*</url-pattern>
</servlet-mapping> </servlet-mapping>
<!-- used to provide the ability to enter Chinese characters inside the Owner Form -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Dandelion filter definition and mapping --> <!-- Dandelion filter definition and mapping -->
<filter> <filter>
<filter-name>dandelionFilter</filter-name> <filter-name>dandelionFilter</filter-name>
@ -101,25 +120,6 @@ see here: http://static.springsource.org/spring/docs/current/spring-framework-re
<servlet-name>petclinic</servlet-name> <servlet-name>petclinic</servlet-name>
</filter-mapping> </filter-mapping>
<!-- used to provide the ability to enter Chinese characters inside the Owner Form -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Dandelion-Datatables filter, used for basic export --> <!-- Dandelion-Datatables filter, used for basic export -->
<filter> <filter>
<filter-name>datatables</filter-name> <filter-name>datatables</filter-name>

View file

@ -38,7 +38,7 @@ import org.springframework.transaction.annotation.Transactional;
* TestContext Framework: </p> <ul> <li><strong>Spring IoC container caching</strong> which spares us unnecessary set up * TestContext Framework: </p> <ul> <li><strong>Spring IoC container caching</strong> which spares us unnecessary set up
* time between test execution.</li> <li><strong>Dependency Injection</strong> of test fixture instances, meaning that * time between test execution.</li> <li><strong>Dependency Injection</strong> of test fixture instances, meaning that
* we don't need to perform application context lookups. See the use of {@link Autowired @Autowired} on the <code>{@link * we don't need to perform application context lookups. See the use of {@link Autowired @Autowired} on the <code>{@link
* AbstractclinicServiceTests#clinicService clinicService}</code> instance variable, which uses autowiring <em>by * AbstractClinicServiceTests#clinicService clinicService}</code> instance variable, which uses autowiring <em>by
* type</em>. <li><strong>Transaction management</strong>, meaning each test method is executed in its own transaction, * type</em>. <li><strong>Transaction management</strong>, meaning each test method is executed in its own transaction,
* which is automatically rolled back by default. Thus, even if tests insert or otherwise change database state, there * which is automatically rolled back by default. Thus, even if tests insert or otherwise change database state, there
* is no need for a teardown or cleanup script. <li> An {@link org.springframework.context.ApplicationContext * is no need for a teardown or cleanup script. <li> An {@link org.springframework.context.ApplicationContext

View file

@ -25,8 +25,6 @@ import org.springframework.web.context.WebApplicationContext;
/** /**
* Test class for the UserResource REST controller. * Test class for the UserResource REST controller.
*
* @see UserResource
*/ */
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration @WebAppConfiguration
@ -39,9 +37,6 @@ public class VetControllerTests {
@Autowired @Autowired
private VetController vetController; private VetController vetController;
@Autowired
private WebApplicationContext ctx;
private MockMvc mockMvc; private MockMvc mockMvc;
@Before @Before