migration to JPA annotations

- added JPA annotations to POJO classes
- merged JPA Repos with Hibernate repos so we only use JPA
- renamed .txt files to .sql
- moved Spring configuration files so it is easier to use them inside
JUnit tests
This commit is contained in:
Mic 2013-01-14 16:12:05 +08:00
parent 099847cf49
commit 9f8acc05ad
34 changed files with 142 additions and 349 deletions

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<beansProjectDescription>
<version>1</version>
<pluginVersion><![CDATA[2.3.0.200912170948-RELEASE]]></pluginVersion>
<pluginVersion><![CDATA[3.2.0.201211290605-M1]]></pluginVersion>
<configSuffixes>
<configSuffix><![CDATA[xml]]></configSuffix>
</configSuffixes>

View file

@ -1,5 +1,8 @@
package org.springframework.samples.petclinic;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
/**
* Simple JavaBean domain object with an id property.
* Used as a base class for objects needing this property.
@ -7,9 +10,10 @@ package org.springframework.samples.petclinic;
* @author Ken Krebs
* @author Juergen Hoeller
*/
@MappedSuperclass
public class BaseEntity {
private Integer id;
@Id
protected Integer id;
public void setId(Integer id) {

View file

@ -43,7 +43,7 @@ public interface Clinic {
* @return the <code>Owner</code> if found
* @throws org.springframework.dao.DataRetrievalFailureException if not found
*/
Owner loadOwner(int id) throws DataAccessException;
Owner findOwner(int id) throws DataAccessException;
/**
* Retrieve a <code>Pet</code> from the data store by id.
@ -51,7 +51,7 @@ public interface Clinic {
* @return the <code>Pet</code> if found
* @throws org.springframework.dao.DataRetrievalFailureException if not found
*/
Pet loadPet(int id) throws DataAccessException;
Pet findPet(int id) throws DataAccessException;
/**
* Save an <code>Owner</code> to the data store, either inserting or updating it.

View file

@ -1,5 +1,8 @@
package org.springframework.samples.petclinic;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
/**
* Simple JavaBean domain object adds a name property to <code>BaseEntity</code>.
* Used as a base class for objects needing these properties.
@ -7,8 +10,10 @@ package org.springframework.samples.petclinic;
* @author Ken Krebs
* @author Juergen Hoeller
*/
@MappedSuperclass
public class NamedEntity extends BaseEntity {
@Column(name="name")
private String name;

View file

@ -6,6 +6,12 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.springframework.beans.support.MutableSortDefinition;
import org.springframework.beans.support.PropertyComparator;
import org.springframework.core.style.ToStringCreator;
@ -17,14 +23,18 @@ import org.springframework.core.style.ToStringCreator;
* @author Juergen Hoeller
* @author Sam Brannen
*/
@Entity @Table(name="owners")
public class Owner extends Person {
@Column(name="address")
private String address;
@Column(name="city")
private String city;
@Column(name="telephone")
private String telephone;
@OneToMany(cascade=CascadeType.ALL, mappedBy="owner")
private Set<Pet> pets;

View file

@ -1,15 +1,21 @@
package org.springframework.samples.petclinic;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
/**
* Simple JavaBean domain object representing an person.
*
* @author Ken Krebs
*/
@MappedSuperclass
public class Person extends BaseEntity {
@Column(name="first_name")
protected String firstName;
private String firstName;
private String lastName;
@Column(name="last_name")
protected String lastName;
public String getFirstName() {
return this.firstName;

View file

@ -7,6 +7,14 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.springframework.beans.support.MutableSortDefinition;
import org.springframework.beans.support.PropertyComparator;
@ -17,14 +25,21 @@ import org.springframework.beans.support.PropertyComparator;
* @author Juergen Hoeller
* @author Sam Brannen
*/
@Entity @Table(name="pets")
public class Pet extends NamedEntity {
@Column(name="birth_date")
private Date birthDate;
@ManyToOne
@JoinColumn(name = "type_id")
private PetType type;
@ManyToOne
@JoinColumn(name = "owner_id")
private Owner owner;
@OneToMany(cascade=CascadeType.ALL, mappedBy="pet")
private Set<Visit> visits;

View file

@ -1,8 +1,12 @@
package org.springframework.samples.petclinic;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* @author Juergen Hoeller
*/
@Entity @Table(name="types")
public class PetType extends NamedEntity {
}

View file

@ -1,10 +1,14 @@
package org.springframework.samples.petclinic;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* Models a {@link Vet Vet's} specialty (for example, dentistry).
*
* @author Juergen Hoeller
*/
@Entity @Table(name="specialties")
public class Specialty extends NamedEntity {
}

View file

@ -5,6 +5,10 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlElement;
import org.springframework.beans.support.MutableSortDefinition;
@ -18,8 +22,10 @@ import org.springframework.beans.support.PropertyComparator;
* @author Sam Brannen
* @author Arjen Poutsma
*/
@Entity @Table(name="vets")
public class Vet extends Person {
@ManyToMany
private Set<Specialty> specialties;

View file

@ -2,20 +2,31 @@ package org.springframework.samples.petclinic;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
* Simple JavaBean domain object representing a visit.
*
* @author Ken Krebs
*/
@Entity @Table(name="visits")
public class Visit extends BaseEntity {
/** Holds value of property date. */
@Column(name="visit_date")
private Date date;
/** Holds value of property description. */
@Column(name="description")
private String description;
/** Holds value of property pet. */
@ManyToOne
@JoinColumn(name = "pet_id")
private Pet pet;

View file

@ -1,98 +0,0 @@
package org.springframework.samples.petclinic.hibernate;
import java.util.Collection;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.samples.petclinic.Clinic;
import org.springframework.samples.petclinic.Owner;
import org.springframework.samples.petclinic.Pet;
import org.springframework.samples.petclinic.PetType;
import org.springframework.samples.petclinic.Vet;
import org.springframework.samples.petclinic.Visit;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
/**
* Hibernate implementation of the Clinic interface.
*
* <p>The mappings are defined in "petclinic.hbm.xml", located in the root of the
* class path.
*
* <p>Note that transactions are declared with annotations and that some methods
* contain "readOnly = true" which is an optimization that is particularly
* valuable when using Hibernate (to suppress unnecessary flush attempts for
* read-only operations).
*
* @author Juergen Hoeller
* @author Sam Brannen
* @author Mark Fisher
* @since 19.10.2003
*/
@Repository
@Transactional
public class HibernateClinic implements Clinic {
private SessionFactory sessionFactory;
@Autowired
public HibernateClinic(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public Collection<Vet> getVets() {
return sessionFactory.getCurrentSession().createQuery("from Vet vet order by vet.lastName, vet.firstName").list();
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public Collection<PetType> getPetTypes() {
return sessionFactory.getCurrentSession().createQuery("from PetType type order by type.name").list();
}
@Transactional(readOnly = true)
@SuppressWarnings("unchecked")
public Collection<Owner> findOwners(String lastName) {
return sessionFactory.getCurrentSession().createQuery("from Owner owner where owner.lastName like :lastName")
.setString("lastName", lastName + "%").list();
}
@Transactional(readOnly = true)
public Owner loadOwner(int id) {
return (Owner) sessionFactory.getCurrentSession().load(Owner.class, id);
}
@Transactional(readOnly = true)
public Pet loadPet(int id) {
return (Pet) sessionFactory.getCurrentSession().load(Pet.class, id);
}
public void storeOwner(Owner owner) {
// Note: Hibernate3's merge operation does not reassociate the object
// with the current Hibernate Session. Instead, it will always copy the
// state over to a registered representation of the entity. In case of a
// new entity, it will register a copy as well, but will not update the
// id of the passed-in object. To still update the ids of the original
// objects too, we need to register Spring's
// IdTransferringMergeEventListener on our SessionFactory.
sessionFactory.getCurrentSession().merge(owner);
}
public void storePet(Pet pet) {
sessionFactory.getCurrentSession().merge(pet);
}
public void storeVisit(Visit visit) {
sessionFactory.getCurrentSession().merge(visit);
}
public void deletePet(int id) throws DataAccessException {
Pet pet = loadPet(id);
sessionFactory.getCurrentSession().delete(pet);
}
}

View file

@ -1,9 +0,0 @@
/**
*
* The classes in this package represent the Hibernate implementation
* of PetClinic's persistence layer.
*
*/
package org.springframework.samples.petclinic.hibernate;

View file

@ -163,7 +163,7 @@ public class SimpleJdbcClinic implements Clinic, SimpleJdbcClinicMBean {
* owner, if not already loaded.
*/
@Transactional(readOnly = true)
public Owner loadOwner(int id) throws DataAccessException {
public Owner findOwner(int id) throws DataAccessException {
Owner owner;
try {
owner = this.simpleJdbcTemplate.queryForObject(
@ -179,7 +179,7 @@ public class SimpleJdbcClinic implements Clinic, SimpleJdbcClinicMBean {
}
@Transactional(readOnly = true)
public Pet loadPet(int id) throws DataAccessException {
public Pet findPet(int id) throws DataAccessException {
JdbcPet pet;
try {
pet = this.simpleJdbcTemplate.queryForObject(
@ -190,7 +190,7 @@ public class SimpleJdbcClinic implements Clinic, SimpleJdbcClinicMBean {
catch (EmptyResultDataAccessException ex) {
throw new ObjectRetrievalFailureException(Pet.class, new Integer(id));
}
Owner owner = loadOwner(pet.getOwnerId());
Owner owner = findOwner(pet.getOwnerId());
owner.addPet(pet);
pet.setType(EntityUtils.getById(getPetTypes(), PetType.class, pet.getTypeId()));
loadVisits(pet);

View file

@ -55,12 +55,12 @@ public class EntityManagerClinic implements Clinic {
}
@Transactional(readOnly = true)
public Owner loadOwner(int id) {
public Owner findOwner(int id) {
return this.em.find(Owner.class, id);
}
@Transactional(readOnly = true)
public Pet loadPet(int id) {
public Pet findPet(int id) {
return this.em.find(Pet.class, id);
}
@ -89,7 +89,7 @@ public class EntityManagerClinic implements Clinic {
}
public void deletePet(int id) throws DataAccessException {
Pet pet = loadPet(id);
Pet pet = findPet(id);
this.em.remove(pet);
}

View file

@ -54,7 +54,7 @@ public class AddPetController {
@RequestMapping(method = RequestMethod.GET)
public String setupForm(@PathVariable("ownerId") int ownerId, Model model) {
Owner owner = this.clinic.loadOwner(ownerId);
Owner owner = this.clinic.findOwner(ownerId);
Pet pet = new Pet();
owner.addPet(pet);
model.addAttribute("pet", pet);

View file

@ -46,7 +46,7 @@ public class AddVisitController {
@RequestMapping(method = RequestMethod.GET)
public String setupForm(@PathVariable("petId") int petId, Model model) {
Pet pet = this.clinic.loadPet(petId);
Pet pet = this.clinic.findPet(petId);
Visit visit = new Visit();
pet.addVisit(visit);
model.addAttribute("visit", visit);

View file

@ -71,7 +71,7 @@ public class ClinicController {
@RequestMapping("/owners/{ownerId}")
public ModelAndView showOwner(@PathVariable("ownerId") int ownerId) {
ModelAndView mav = new ModelAndView("owners/show");
mav.addObject(this.clinic.loadOwner(ownerId));
mav.addObject(this.clinic.findOwner(ownerId));
return mav;
}
@ -84,7 +84,7 @@ public class ClinicController {
@RequestMapping(value="/owners/*/pets/{petId}/visits", method=RequestMethod.GET)
public ModelAndView visitsHandler(@PathVariable int petId) {
ModelAndView mav = new ModelAndView("visits");
mav.addObject("visits", this.clinic.loadPet(petId).getVisits());
mav.addObject("visits", this.clinic.findPet(petId).getVisits());
return mav;
}

View file

@ -44,7 +44,7 @@ public class EditOwnerController {
@RequestMapping(method = RequestMethod.GET)
public String setupForm(@PathVariable("ownerId") int ownerId, Model model) {
Owner owner = this.clinic.loadOwner(ownerId);
Owner owner = this.clinic.findOwner(ownerId);
model.addAttribute(owner);
return "owners/form";
}

View file

@ -52,7 +52,7 @@ public class EditPetController {
@RequestMapping(method = RequestMethod.GET)
public String setupForm(@PathVariable("petId") int petId, Model model) {
Pet pet = this.clinic.loadPet(petId);
Pet pet = this.clinic.findPet(petId);
model.addAttribute("pet", pet);
return "pets/form";
}
@ -72,7 +72,7 @@ public class EditPetController {
@RequestMapping(method = RequestMethod.DELETE)
public String deletePet(@PathVariable int petId) {
Pet pet = this.clinic.loadPet(petId);
Pet pet = this.clinic.findPet(petId);
this.clinic.deletePet(petId);
return "redirect:/owners/" + pet.getOwner().getId();
}

View file

@ -15,7 +15,7 @@
<!-- Configurer that replaces ${...} placeholders with values from a properties file -->
<!-- (in this case, JDBC-related settings for the dataSource definition below) -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<context:property-placeholder location="classpath:spring/jdbc.properties"/>
<!-- DataSource configuration for Apache Commons DBCP. -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"

View file

@ -16,33 +16,23 @@
<!-- import the dataSource definition -->
<import resource="applicationContext-dataSource.xml"/>
<!--
Activates a load-time weaver for the context. Any bean within the context that
implements LoadTimeWeaverAware (such as LocalContainerEntityManagerFactoryBean)
will receive a reference to the autodetected load-time weaver.
-->
<context:load-time-weaver/>
<!-- Configurer that replaces ${...} placeholders with values from a properties file -->
<!-- (in this case, JDBC-related settings for the JPA EntityManager definition below) -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<context:property-placeholder location="classpath:spring/jdbc.properties"/>
<!-- JPA EntityManagerFactory -->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter"
p:databasePlatform="${jpa.databasePlatform}" p:showSql="${jpa.showSql}"/>
<!--
<bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter"
p:database="${jpa.database}" p:showSql="${jpa.showSql}"/>
-->
<!--
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:database="${jpa.database}" p:showSql="${jpa.showSql}"/>
-->
p:database="${jpa.database}" p:showSql="${jpa.showSql}"/>
</property>
<property name="packagesToScan">
<list>
<value>org/springframework/samples/petclinic</value>
</list>
</property>
<property name="persistenceXmlLocation" value="classpath:META-INF/jpa-persistence.xml"/>
</bean>
<!-- Transaction manager for a single JPA EntityManagerFactory (alternative to JTA) -->

View file

@ -22,8 +22,8 @@ jdbc.username=sa
jdbc.password=
# Properties that control the population of schema and data for a new data source
jdbc.initLocation=classpath:db/hsqldb/initDB.txt
jdbc.dataLocation=classpath:db/hsqldb/populateDB.txt
jdbc.initLocation=classpath:db/hsqldb/initDB.sql
jdbc.dataLocation=classpath:db/hsqldb/populateDB.sql
# Property that determines which Hibernate dialect to use
# (only applied with "applicationContext-hibernate.xml")

View file

@ -1,77 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Application context definition for PetClinic on Hibernate.
-->
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- ========================= RESOURCE DEFINITIONS ========================= -->
<!-- import the dataSource definition -->
<import resource="applicationContext-dataSource.xml"/>
<!-- Configurer that replaces ${...} placeholders with values from a properties file -->
<!-- (in this case, Hibernate-related settings for the sessionFactory definition below) -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
p:dataSource-ref="dataSource" p:mappingResources="petclinic.hbm.xml">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
</props>
</property>
<property name="eventListeners">
<map>
<entry key="merge">
<bean class="org.springframework.orm.hibernate4.support.IdTransferringMergeEventListener"/>
</entry>
</map>
</property>
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory"/>
<!-- Transaction manager that delegates to JTA (for a transactional JNDI DataSource) -->
<!--
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
-->
<!-- ========================= BUSINESS OBJECT DEFINITIONS ========================= -->
<!--
Activates various annotations to be detected in bean classes:
Spring's @Required and @Autowired, as well as JSR 250's @Resource.
-->
<context:annotation-config/>
<!--
Instruct Spring to perform declarative transaction management
automatically on annotated classes.
-->
<tx:annotation-driven/>
<!--
Exporter that exposes the Hibernate statistics service via JMX. Autodetects the
service MBean, using its bean name as JMX object name.
-->
<context:mbean-export/>
<!-- PetClinic's central data access object: Hibernate implementation -->
<bean id="clinic" class="org.springframework.samples.petclinic.hibernate.HibernateClinic"/>
<!-- Hibernate's JMX statistics service -->
<bean name="petclinic:type=HibernateStatistics" class="org.hibernate.jmx.StatisticsService" autowire="byName"/>
</beans>

View file

@ -37,7 +37,7 @@
-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/applicationContext-jdbc.xml</param-value>
<param-value>classpath:spring/applicationContext-jdbc.xml</param-value>
<!--
<param-value>/WEB-INF/spring/applicationContext-hibernate.xml</param-value>
<param-value>/WEB-INF/spring/applicationContext-jpa.xml</param-value>

View file

@ -123,9 +123,9 @@ public abstract class AbstractClinicTests {
@Test
public void loadOwner() {
Owner o1 = this.clinic.loadOwner(1);
Owner o1 = this.clinic.findOwner(1);
assertTrue(o1.getLastName().startsWith("Franklin"));
Owner o10 = this.clinic.loadOwner(10);
Owner o10 = this.clinic.findOwner(10);
assertEquals("Carlos", o10.getFirstName());
// XXX: Add programmatic support for ending transactions with the
@ -154,22 +154,22 @@ public abstract class AbstractClinicTests {
@Test
public void updateOwner() throws Exception {
Owner o1 = this.clinic.loadOwner(1);
Owner o1 = this.clinic.findOwner(1);
String old = o1.getLastName();
o1.setLastName(old + "X");
this.clinic.storeOwner(o1);
o1 = this.clinic.loadOwner(1);
o1 = this.clinic.findOwner(1);
assertEquals(old + "X", o1.getLastName());
}
@Test
public void loadPet() {
Collection<PetType> types = this.clinic.getPetTypes();
Pet p7 = this.clinic.loadPet(7);
Pet p7 = this.clinic.findPet(7);
assertTrue(p7.getName().startsWith("Samantha"));
assertEquals(EntityUtils.getById(types, PetType.class, 1).getId(), p7.getType().getId());
assertEquals("Jean", p7.getOwner().getFirstName());
Pet p6 = this.clinic.loadPet(6);
Pet p6 = this.clinic.findPet(6);
assertEquals("George", p6.getName());
assertEquals(EntityUtils.getById(types, PetType.class, 4).getId(), p6.getType().getId());
assertEquals("Peter", p6.getOwner().getFirstName());
@ -177,7 +177,7 @@ public abstract class AbstractClinicTests {
@Test
public void insertPet() {
Owner o6 = this.clinic.loadOwner(6);
Owner o6 = this.clinic.findOwner(6);
int found = o6.getPets().size();
Pet pet = new Pet();
pet.setName("bowser");
@ -190,23 +190,23 @@ public abstract class AbstractClinicTests {
this.clinic.storePet(pet);
this.clinic.storeOwner(o6);
// assertTrue(!pet.isNew()); -- NOT TRUE FOR TOPLINK (before commit)
o6 = this.clinic.loadOwner(6);
o6 = this.clinic.findOwner(6);
assertEquals(found + 1, o6.getPets().size());
}
@Test
public void updatePet() throws Exception {
Pet p7 = this.clinic.loadPet(7);
Pet p7 = this.clinic.findPet(7);
String old = p7.getName();
p7.setName(old + "X");
this.clinic.storePet(p7);
p7 = this.clinic.loadPet(7);
p7 = this.clinic.findPet(7);
assertEquals(old + "X", p7.getName());
}
@Test
public void insertVisit() {
Pet p7 = this.clinic.loadPet(7);
Pet p7 = this.clinic.findPet(7);
int found = p7.getVisits().size();
Visit visit = new Visit();
p7.addVisit(visit);
@ -215,7 +215,7 @@ public abstract class AbstractClinicTests {
this.clinic.storeVisit(visit);
this.clinic.storePet(p7);
// assertTrue(!visit.isNew()); -- NOT TRUE FOR TOPLINK (before commit)
p7 = this.clinic.loadPet(7);
p7 = this.clinic.findPet(7);
assertEquals(found + 1, p7.getVisits().size());
}

View file

@ -1,4 +1,4 @@
package org.springframework.samples.petclinic.jpa;
package org.springframework.samples.petclinic.aspects;
import java.util.List;
@ -6,6 +6,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.samples.petclinic.aspects.UsageLogAspect;
import org.springframework.samples.petclinic.jpa.JpaClinicTests;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static junit.framework.Assert.assertTrue;
@ -24,10 +25,9 @@ import static junit.framework.Assert.assertFalse;
* @author Rod Johnson
* @author Juergen Hoeller
*/
@ContextConfiguration(locations={"applicationContext-jpaCommon.xml", "applicationContext-hibernateAdapter.xml",
"applicationContext-entityManager.xml"})
@ContextConfiguration(locations={"classpath:spring/applicationContext-jpa.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class EntityManagerClinicTests extends AbstractJpaClinicTests {
public class UsageLogAspectTests extends JpaClinicTests {
@Autowired
private UsageLogAspect usageLogAspect;

View file

@ -1,25 +0,0 @@
package org.springframework.samples.petclinic.hibernate;
import org.junit.runner.RunWith;
import org.springframework.samples.petclinic.AbstractClinicTests;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* <p>
* Integration tests for the {@link HibernateClinic} implementation.
* </p>
* <p>
* "HibernateClinicTests-context.xml" determines the actual beans to test.
* </p>
*
* @author Juergen Hoeller
* @author Sam Brannen
*/
@ContextConfiguration
@DirtiesContext
@RunWith(SpringJUnit4ClassRunner.class)
public class HibernateClinicTests extends AbstractClinicTests {
}

View file

@ -1,24 +0,0 @@
package org.springframework.samples.petclinic.jpa;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* <p>
* Tests for the DAO variant based on the shared EntityManager approach, using
* Hibernate EntityManager for testing instead of the reference implementation.
* </p>
* <p>
* Specifically tests usage of an <code>orm.xml</code> file, loaded by the
* persistence provider through the Spring-provided persistence unit root URL.
* </p>
*
* @author Juergen Hoeller
*/
@ContextConfiguration(locations={"applicationContext-jpaCommon.xml", "applicationContext-hibernateAdapter.xml",
"applicationContext-entityManager.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class HibernateEntityManagerClinicTests extends EntityManagerClinicTests {
}

View file

@ -12,6 +12,7 @@ import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.samples.petclinic.Clinic;
import org.springframework.samples.petclinic.Owner;
@ -20,18 +21,12 @@ import org.springframework.samples.petclinic.PetType;
import org.springframework.samples.petclinic.Vet;
import org.springframework.samples.petclinic.Visit;
import org.springframework.samples.petclinic.util.EntityUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* <p>
* This class extends {@link AbstractJpaTests}, one of the valuable test
* superclasses provided in the <code>org.springframework.test</code> package.
* This represents best practice for integration tests with Spring for JPA based
* tests which require <em>shadow class loading</em>. For all other types of
* integration testing, the <em>Spring TestContext Framework</em> is
* preferred.
* </p>
* <p>
* AbstractJpaTests and its superclasses provide the following services:
* Provides the following services:
* <ul>
* <li>Injects test dependencies, meaning that we don't need to perform
* application context lookups. See the setClinic() method. Injection uses
@ -41,15 +36,16 @@ import org.springframework.samples.petclinic.util.EntityUtils;
* change database state, there is no need for a teardown or cleanup script.</li>
* </ul>
* <p>
* {@link AbstractJpaTests} and related classes are shipped in
* <code>spring-test.jar</code>.
* </p>
* </p>
*
* @author Rod Johnson
* @author Sam Brannen
* @see AbstractJpaTests
* @author Michael Isvy
*/
public abstract class AbstractJpaClinicTests {
@ContextConfiguration(locations={"classpath:spring/applicationContext-jpa.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class JpaClinicTests {
@PersistenceContext
private EntityManager entityManager;
@ -103,10 +99,10 @@ public abstract class AbstractJpaClinicTests {
}
@Test
public void testLoadOwner() {
Owner o1 = this.clinic.loadOwner(1);
public void tesFindOwner() {
Owner o1 = this.clinic.findOwner(1);
assertTrue(o1.getLastName().startsWith("Franklin"));
Owner o10 = this.clinic.loadOwner(10);
Owner o10 = this.clinic.findOwner(10);
assertEquals("Carlos", o10.getFirstName());
}
@ -124,22 +120,22 @@ public abstract class AbstractJpaClinicTests {
@Test
public void testUpdateOwner() throws Exception {
Owner o1 = this.clinic.loadOwner(1);
Owner o1 = this.clinic.findOwner(1);
String old = o1.getLastName();
o1.setLastName(old + "X");
this.clinic.storeOwner(o1);
o1 = this.clinic.loadOwner(1);
o1 = this.clinic.findOwner(1);
assertEquals(old + "X", o1.getLastName());
}
@Test
public void testLoadPet() {
public void testFindPet() {
Collection<PetType> types = this.clinic.getPetTypes();
Pet p7 = this.clinic.loadPet(7);
Pet p7 = this.clinic.findPet(7);
assertTrue(p7.getName().startsWith("Samantha"));
assertEquals(EntityUtils.getById(types, PetType.class, 1).getId(), p7.getType().getId());
assertEquals("Jean", p7.getOwner().getFirstName());
Pet p6 = this.clinic.loadPet(6);
Pet p6 = this.clinic.findPet(6);
assertEquals("George", p6.getName());
assertEquals(EntityUtils.getById(types, PetType.class, 4).getId(), p6.getType().getId());
assertEquals("Peter", p6.getOwner().getFirstName());
@ -147,7 +143,7 @@ public abstract class AbstractJpaClinicTests {
@Test
public void testInsertPet() {
Owner o6 = this.clinic.loadOwner(6);
Owner o6 = this.clinic.findOwner(6);
int found = o6.getPets().size();
Pet pet = new Pet();
pet.setName("bowser");
@ -158,30 +154,30 @@ public abstract class AbstractJpaClinicTests {
assertEquals(found + 1, o6.getPets().size());
this.clinic.storeOwner(o6);
// assertTrue(!pet.isNew()); -- NOT TRUE FOR TOPLINK (before commit)
o6 = this.clinic.loadOwner(6);
o6 = this.clinic.findOwner(6);
assertEquals(found + 1, o6.getPets().size());
}
@Test
public void testUpdatePet() throws Exception {
Pet p7 = this.clinic.loadPet(7);
Pet p7 = this.clinic.findPet(7);
String old = p7.getName();
p7.setName(old + "X");
this.clinic.storePet(p7);
p7 = this.clinic.loadPet(7);
p7 = this.clinic.findPet(7);
assertEquals(old + "X", p7.getName());
}
@Test
public void testInsertVisit() {
Pet p7 = this.clinic.loadPet(7);
Pet p7 = this.clinic.findPet(7);
int found = p7.getVisits().size();
Visit visit = new Visit();
p7.addVisit(visit);
visit.setDescription("test");
this.clinic.storePet(p7);
// assertTrue(!visit.isNew()); -- NOT TRUE FOR TOPLINK (before commit)
p7 = this.clinic.loadPet(7);
p7 = this.clinic.findPet(7);
assertEquals(found + 1, p7.getVisits().size());
}
}

View file

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.springframework.samples.petclinic.hibernate.HibernateClinic">
<constructor-arg ref="sessionFactory"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
p:dataSource-ref="dataSource" p:mappingResources="petclinic.hbm.xml">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
</beans>