SPRING IN ACTION 第4版笔记-第十一章Persisting data with object-relational mapping-001-使用Hibernate(@Inject、@EnableTransactionManagement、@Repository、PersistenceExceptionTranslationPostProcessor)

一、结构

二、Repository层

1.

 1 package spittr.db;
 2 
 3 import java.util.List;
 4 
 5 import spittr.domain.Spitter;
 6 
 7 /**
 8  * Repository interface with operations for {@link Spitter} persistence.
 9  * @author habuma
10  */
11 public interface SpitterRepository {
12 
13   long count();
14 
15   Spitter save(Spitter spitter);
16 
17   Spitter findOne(long id);
18 
19   Spitter findByUsername(String username);
20 
21   List<Spitter> findAll();
22 
23 }

2.

 1 package spittr.db;
 2 
 3 import java.util.List;
 4 
 5 import spittr.domain.Spittle;
 6 
 7 /**
 8  * Repository interface with operations for {@link Spittle} persistence.
 9  * @author habuma
10  */
11 public interface SpittleRepository {
12 
13   long count();
14 
15   List<Spittle> findRecent();
16 
17   List<Spittle> findRecent(int count);
18 
19   Spittle findOne(long id);
20 
21   Spittle save(Spittle spittle);
22 
23   List<Spittle> findBySpitterId(long spitterId);
24   
25   void delete(long id);
26 
27 }

3.以前是用HibernateTemplate,但现在的最佳实践是用Hibernate contextual sessions and not use HibernateTemplate at all. This can be done by wiring a Hibernate SessionFactory directly into your repository and using it to obtain a session

@Repository有两作用:

(1)scanned by Spring component-scanning

(2)catch platformspecific exceptions and rethrow them as one of Spring’s unified unchecked exceptions

But if you’re using Hibernate contextual sessions and not a Hibernate template,how can the exception translation take place?要实现第2个作用还要配在配置文件配置PersistenceExceptionTranslationPostProcessor,如:

1 @Bean
2 public BeanPostProcessor persistenceTranslation() {
3     return new PersistenceExceptionTranslationPostProcessor();
4 }
 1 package spittr.db.hibernate4;
 2 
 3 import java.io.Serializable;
 4 import java.util.List;
 5 
 6 import javax.inject.Inject;
 7 
 8 import org.hibernate.Session;
 9 import org.hibernate.SessionFactory;
10 import org.hibernate.criterion.Restrictions;
11 import org.springframework.stereotype.Repository;
12 
13 import spittr.db.SpitterRepository;
14 import spittr.domain.Spitter;
15 
16 @Repository
17 public class HibernateSpitterRepository implements SpitterRepository {
18 
19     private SessionFactory sessionFactory;
20 
21     @Inject
22     public HibernateSpitterRepository(SessionFactory sessionFactory) {
23         this.sessionFactory = sessionFactory;         //<co id="co_InjectSessionFactory"/>
24     }
25     
26     private Session currentSession() {
27         return sessionFactory.getCurrentSession();//<co id="co_RetrieveCurrentSession"/>
28     }
29     
30     public long count() {
31         return findAll().size();
32     }
33 
34     public Spitter save(Spitter spitter) {
35         Serializable id = currentSession().save(spitter);  //<co id="co_UseCurrentSession"/>
36         return new Spitter((Long) id, 
37                 spitter.getUsername(), 
38                 spitter.getPassword(), 
39                 spitter.getFullName(), 
40                 spitter.getEmail(), 
41                 spitter.isUpdateByEmail());
42     }
43 
44     public Spitter findOne(long id) {
45         return (Spitter) currentSession().get(Spitter.class, id); 
46     }
47 
48     public Spitter findByUsername(String username) {        
49         return (Spitter) currentSession() 
50                 .createCriteria(Spitter.class) 
51                 .add(Restrictions.eq("username", username))
52                 .list().get(0);
53     }
54 
55     public List<Spitter> findAll() {
56         return (List<Spitter>) currentSession() 
57                 .createCriteria(Spitter.class).list(); 
58     }
59     
60 }

4.

 1 package spittr.db.hibernate4;
 2 
 3 import java.io.Serializable;
 4 import java.util.List;
 5 
 6 import javax.inject.Inject;
 7 
 8 import org.hibernate.Criteria;
 9 import org.hibernate.Session;
10 import org.hibernate.SessionFactory;
11 import org.hibernate.criterion.Order;
12 import org.hibernate.criterion.Restrictions;
13 import org.springframework.stereotype.Repository;
14 
15 import spittr.db.SpittleRepository;
16 import spittr.domain.Spittle;
17 
18 @Repository
19 public class HibernateSpittleRepository implements SpittleRepository {
20 
21     private SessionFactory sessionFactory;
22 
23     @Inject
24     public HibernateSpittleRepository(SessionFactory sessionFactory) {
25         this.sessionFactory = sessionFactory;
26     }
27     
28     private Session currentSession() {
29         return sessionFactory.getCurrentSession();//<co id="co_RetrieveCurrentSession"/>
30     }
31 
32     public long count() {
33         return findAll().size(); 
34     }
35 
36     public List<Spittle> findRecent() {
37         return findRecent(10);
38     }
39 
40     public List<Spittle> findRecent(int count) {
41         return (List<Spittle>) spittleCriteria()
42                 .setMaxResults(count)
43                 .list();
44     }
45 
46     public Spittle findOne(long id) {
47         return (Spittle) currentSession().get(Spittle.class, id);
48     }
49 
50     public Spittle save(Spittle spittle) {
51         Serializable id = currentSession().save(spittle);
52         return new Spittle(
53             (Long) id, 
54             spittle.getSpitter(), 
55             spittle.getMessage(), 
56             spittle.getPostedTime());
57     }
58 
59     public List<Spittle> findBySpitterId(long spitterId) {
60         return spittleCriteria()
61                 .add(Restrictions.eq("spitter.id", spitterId))
62                 .list();
63     }
64     
65     public void delete(long id) {
66         currentSession().delete(findOne(id));
67     }
68     
69     public List<Spittle> findAll() {
70         return (List<Spittle>) spittleCriteria().list(); 
71     }
72     
73     private Criteria spittleCriteria() {
74         return currentSession() 
75                 .createCriteria(Spittle.class)
76                 .addOrder(Order.desc("postedTime"));
77     }
78 
79 }

三、Domainn层

1.

 1 package spittr.domain;
 2 
 3 import javax.persistence.Column;
 4 import javax.persistence.Entity;
 5 import javax.persistence.GeneratedValue;
 6 import javax.persistence.GenerationType;
 7 import javax.persistence.Id;
 8 
 9 
10 @Entity
11 public class Spitter {
12     
13     private Spitter() {}
14 
15     @Id
16     @GeneratedValue(strategy=GenerationType.IDENTITY)
17     private Long id;
18 
19     @Column(name="username")
20     private String username;
21 
22     @Column(name="password")
23     private String password;
24 
25     @Column(name="fullname")
26     private String fullName;
27 
28     @Column(name="email")
29     private String email;
30 
31     @Column(name="updateByEmail")
32     private boolean updateByEmail;
33 
34     public Spitter(Long id, String username, String password, String fullName,
35             String email, boolean updateByEmail) {
36         this.id = id;
37         this.username = username;
38         this.password = password;
39         this.fullName = fullName;
40         this.email = email;
41         this.updateByEmail = updateByEmail;
42     }
43 
44     public Long getId() {
45         return id;
46     }
47 
48     public String getUsername() {
49         return username;
50     }
51 
52     public String getPassword() {
53         return password;
54     }
55 
56     public String getFullName() {
57         return fullName;
58     }
59 
60     public String getEmail() {
61         return email;
62     }
63 
64     public boolean isUpdateByEmail() {
65         return updateByEmail;
66     }
67 
68 }

2.

 1 package spittr.domain;
 2 
 3 import java.util.Date;
 4 
 5 import javax.persistence.Column;
 6 import javax.persistence.Entity;
 7 import javax.persistence.GeneratedValue;
 8 import javax.persistence.GenerationType;
 9 import javax.persistence.Id;
10 import javax.persistence.JoinColumn;
11 import javax.persistence.ManyToOne;
12 
13 @Entity
14 public class Spittle {
15     
16     private Spittle() {}
17     
18     @Id
19     @GeneratedValue(strategy=GenerationType.IDENTITY)
20     private Long id;
21     
22     @ManyToOne
23     @JoinColumn(name="spitter")
24     private Spitter spitter;
25     
26     @Column
27     private String message;
28     
29     @Column
30     private Date postedTime;
31 
32     public Spittle(Long id, Spitter spitter, String message, Date postedTime) {
33         this.id = id;
34         this.spitter = spitter;
35         this.message = message;
36         this.postedTime = postedTime;
37     }
38 
39     public Long getId() {
40         return this.id;
41     }
42 
43     public String getMessage() {
44         return this.message;
45     }
46 
47     public Date getPostedTime() {
48         return this.postedTime;
49     }
50 
51     public Spitter getSpitter() {
52         return this.spitter;
53     }
54 
55 }

 

四、配置文件及数据库文件

0.

 1 package spittr.db.hibernate4;
 2 
 3 import java.io.IOException;
 4 import java.util.Properties;
 5 
 6 import javax.inject.Inject;
 7 import javax.sql.DataSource;
 8 
 9 import org.hibernate.SessionFactory;
10 import org.springframework.context.annotation.Bean;
11 import org.springframework.context.annotation.ComponentScan;
12 import org.springframework.context.annotation.Configuration;
13 import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
14 import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
15 import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
16 //import org.springframework.orm.hibernate4.HibernateTransactionManager;
17 //import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
18 import org.springframework.orm.hibernate5.HibernateTransactionManager;
19 import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
20 import org.springframework.transaction.PlatformTransactionManager;
21 import org.springframework.transaction.annotation.EnableTransactionManagement;
22 import org.springframework.transaction.annotation.TransactionManagementConfigurer;
23 
24 @Configuration
25 @EnableTransactionManagement
26 @ComponentScan
27 public class RepositoryTestConfig implements TransactionManagementConfigurer {
28 
29   @Inject
30   private SessionFactory sessionFactory;
31 
32   @Bean
33   public DataSource dataSource() {
34     EmbeddedDatabaseBuilder edb = new EmbeddedDatabaseBuilder();
35     edb.setType(EmbeddedDatabaseType.H2);
36     edb.addScript("spittr/db/hibernate4/schema.sql");
37     edb.addScript("spittr/db/hibernate4/test-data.sql");
38     EmbeddedDatabase embeddedDatabase = edb.build();
39     return embeddedDatabase;
40   }
41 
42   //@Bean
43   public PlatformTransactionManager annotationDrivenTransactionManager() {
44     System.out.println(sessionFactory);
45     HibernateTransactionManager transactionManager = new HibernateTransactionManager();
46     transactionManager.setSessionFactory(sessionFactory);
47     return transactionManager;
48   }
49 
50   @Bean
51   public SessionFactory sessionFactoryBean() {
52     try {
53       LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean();
54       lsfb.setDataSource(dataSource());
55       lsfb.setPackagesToScan("spittr.domain");
56       Properties props = new Properties();
57       props.setProperty("dialect", "org.hibernate.dialect.H2Dialect");
58       lsfb.setHibernateProperties(props);
59       lsfb.afterPropertiesSet();
60       SessionFactory object = lsfb.getObject();
61       return object;
62     } catch (IOException e) {
63       return null;
64     }
65   }
66 }

1.

1 log4j.rootCategory=INFO, stdout
2 
3 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
4 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
5 log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %40.40c:%4L - %m%n

2.RepositoryTest-context.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
 4     xmlns:c="http://www.springframework.org/schema/c" xmlns:context="http://www.springframework.org/schema/context"
 5     xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
 6         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
 8 
 9 
10     <context:component-scan base-package="spittr.db.hibernate4" />
11 
12      <bean id="transactionManager" 
13          class="org.springframework.orm.hibernate4.HibernateTransactionManager"
14          c:_-ref="sessionFactory" />
15 
16     <jdbc:embedded-database id="dataSource" type="H2">
17         <jdbc:script location="spittr/db/hibernate4/schema.sql" />
18         <jdbc:script location="spittr/db/hibernate4/test-data.sql" />
19     </jdbc:embedded-database>
20 
21      <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
22         <property name="dataSource" ref="dataSource"/>
23         <property name="packagesToScan" value="com.habuma.spitter.domain" />
24         <property name="hibernateProperties">
25             <props>
26                 <prop key="dialect">org.hibernate.dialect.H2Dialect</prop>
27             </props>
28         </property>
29     </bean>
30 
31     <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
32 
33 </beans>

3.schema.sql

 1 drop table if exists spittle;
 2 drop table if exists spitter;
 3 
 4 create table spitter (
 5   id identity,
 6   username varchar(25) not null,
 7   password varchar(25) not null,
 8   fullName varchar(100) not null,
 9   email varchar(50) not null,
10   updateByEmail boolean not null
11 );
12 
13 create table spittle (
14   id integer identity primary key,
15   spitter integer not null,
16   message varchar(2000) not null,
17   postedTime datetime not null,
18   foreign key (spitter) references spitter(id)
19 );

4.test-data.sql

 1 insert into Spitter (username, password, fullname, email, updateByEmail) values ('habuma', 'password', 'Craig Walls', 'craig@habuma.com', false);
 2 insert into Spitter (username, password, fullname, email, updateByEmail) values ('mwalls', 'password', 'Michael Walls', 'mwalls@habuma.com', true);
 3 insert into Spitter (username, password, fullname, email, updateByEmail) values ('chuck', 'password', 'Chuck Wagon', 'chuck@habuma.com', false);
 4 insert into Spitter (username, password, fullname, email, updateByEmail) values ('artnames', 'password', 'Art Names', 'art@habuma.com', true);
 5 
 6 insert into Spittle (spitter, message, postedTime) values (1, 'This is a test spittle message', '2012-06-09 22:00:00Z');
 7 insert into Spittle (spitter, message, postedTime) values (1, 'This is another test spittle message', '2012-06-09 22:10:00Z');
 8 insert into Spittle (spitter, message, postedTime) values (1, 'This is a third test spittle message', '2012-07-04 23:30:00Z');
 9 insert into Spittle (spitter, message, postedTime) values (2, 'Hello from Chuck!', '2012-03-25 12:15:00Z');
10 insert into Spittle (spitter, message, postedTime) values (4, 'Hello from Art!', '2012-03-25 12:15:00Z');
11 insert into Spittle (spitter, message, postedTime) values (4, 'Hello again from Art!', '2012-03-25 12:25:00Z');
12 insert into Spittle (spitter, message, postedTime) values (4, 'Hola from Arthur!', '2012-03-25 12:35:00Z');
13 insert into Spittle (spitter, message, postedTime) values (4, 'Buenos Dias from Art!', '2012-03-25 12:45:00Z');
14 insert into Spittle (spitter, message, postedTime) values (4, 'Ni Hao from Art!', '2012-03-25 12:55:00Z');
15 insert into Spittle (spitter, message, postedTime) values (4, 'Guten Tag from Art!', '2012-03-25 13:05:00Z');
16 insert into Spittle (spitter, message, postedTime) values (4, 'Konnichi wa from Art!', '2012-03-25 13:15:00Z');
17 insert into Spittle (spitter, message, postedTime) values (4, 'Buon giorno from Art!', '2012-03-25 13:25:00Z');
18 insert into Spittle (spitter, message, postedTime) values (4, 'Bonjour from Art!', '2012-03-25 13:35:00Z');
19 insert into Spittle (spitter, message, postedTime) values (4, 'Aloha from Art!', '2012-03-25 13:45:00Z');
20 insert into Spittle (spitter, message, postedTime) values (4, 'God dag from Art!', '2012-03-25 13:55:00Z');

五、测试文件

1.

  1 package spittr.db.hibernate4;
  2 
  3 import static org.junit.Assert.*;
  4 
  5 import java.util.List;
  6 
  7 import org.junit.BeforeClass;
  8 import org.junit.Test;
  9 import org.junit.runner.RunWith;
 10 import org.springframework.beans.factory.annotation.Autowired;
 11 import org.springframework.test.context.ContextConfiguration;
 12 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 13 import org.springframework.transaction.annotation.Transactional;
 14 
 15 import spittr.db.SpitterRepository;
 16 import spittr.domain.Spitter;
 17 
 18 @RunWith(SpringJUnit4ClassRunner.class)
 19 @ContextConfiguration(classes = RepositoryTestConfig.class)
 20 public class SpitterRepositoryTest {
 21 
 22   @Autowired
 23   SpitterRepository spitterRepository;
 24 
 25   @Test
 26   @Transactional
 27   public void count() {
 28     assertEquals(4, spitterRepository.count());
 29   }
 30 
 31   @Test
 32   @Transactional
 33   public void findAll() {
 34     List<Spitter> spitters = spitterRepository.findAll();
 35     assertEquals(4, spitters.size());
 36     assertSpitter(0, spitters.get(0));
 37     assertSpitter(1, spitters.get(1));
 38     assertSpitter(2, spitters.get(2));
 39     assertSpitter(3, spitters.get(3));
 40   }
 41 
 42   @Test
 43   @Transactional
 44   public void findByUsername() {
 45     assertSpitter(0, spitterRepository.findByUsername("habuma"));
 46     assertSpitter(1, spitterRepository.findByUsername("mwalls"));
 47     assertSpitter(2, spitterRepository.findByUsername("chuck"));
 48     assertSpitter(3, spitterRepository.findByUsername("artnames"));
 49   }
 50 
 51   @Test
 52   @Transactional
 53   public void findOne() {
 54     assertSpitter(0, spitterRepository.findOne(1L));
 55     assertSpitter(1, spitterRepository.findOne(2L));
 56     assertSpitter(2, spitterRepository.findOne(3L));
 57     assertSpitter(3, spitterRepository.findOne(4L));
 58   }
 59 
 60   @Test
 61   @Transactional
 62   public void save_newSpitter() {
 63     assertEquals(4, spitterRepository.count());
 64     Spitter spitter = new Spitter(null, "newbee", "letmein", "New Bee",
 65         "newbee@habuma.com", true);
 66     Spitter saved = spitterRepository.save(spitter);
 67     assertEquals(5, spitterRepository.count());
 68     assertSpitter(4, saved);
 69     assertSpitter(4, spitterRepository.findOne(5L));
 70   }
 71 
 72   private static void assertSpitter(int expectedSpitterIndex, Spitter actual) {
 73     assertSpitter(expectedSpitterIndex, actual, "Newbie");
 74   }
 75 
 76   private static void assertSpitter(int expectedSpitterIndex, Spitter actual,
 77       String expectedStatus) {
 78     Spitter expected = SPITTERS[expectedSpitterIndex];
 79     assertEquals(expected.getId(), actual.getId());
 80     assertEquals(expected.getUsername(), actual.getUsername());
 81     assertEquals(expected.getPassword(), actual.getPassword());
 82     assertEquals(expected.getFullName(), actual.getFullName());
 83     assertEquals(expected.getEmail(), actual.getEmail());
 84     assertEquals(expected.isUpdateByEmail(), actual.isUpdateByEmail());
 85   }
 86 
 87   private static Spitter[] SPITTERS = new Spitter[6];
 88 
 89   @BeforeClass
 90   public static void before() {
 91     SPITTERS[0] = new Spitter(1L, "habuma", "password", "Craig Walls",
 92         "craig@habuma.com", false);
 93     SPITTERS[1] = new Spitter(2L, "mwalls", "password", "Michael Walls",
 94         "mwalls@habuma.com", true);
 95     SPITTERS[2] = new Spitter(3L, "chuck", "password", "Chuck Wagon",
 96         "chuck@habuma.com", false);
 97     SPITTERS[3] = new Spitter(4L, "artnames", "password", "Art Names",
 98         "art@habuma.com", true);
 99     SPITTERS[4] = new Spitter(5L, "newbee", "letmein", "New Bee",
100         "newbee@habuma.com", true);
101     SPITTERS[5] = new Spitter(4L, "arthur", "letmein", "Arthur Names",
102         "arthur@habuma.com", false);
103   }
104 
105 }

2.

  1 package spittr.db.hibernate4;
  2 
  3 import static org.junit.Assert.*;
  4 
  5 import java.util.Date;
  6 import java.util.List;
  7 
  8 import org.junit.Test;
  9 import org.junit.runner.RunWith;
 10 import org.springframework.beans.factory.annotation.Autowired;
 11 import org.springframework.test.context.ContextConfiguration;
 12 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 13 import org.springframework.transaction.annotation.Transactional;
 14 
 15 import spittr.db.SpittleRepository;
 16 import spittr.domain.Spitter;
 17 import spittr.domain.Spittle;
 18 
 19 @RunWith(SpringJUnit4ClassRunner.class)
 20 @ContextConfiguration(classes=RepositoryTestConfig.class)
 21 public class SpittleRepositoryTest {
 22     
 23     @Autowired
 24     SpittleRepository spittleRepository;
 25 
 26     @Test
 27     @Transactional
 28     public void count() {
 29         assertEquals(15, spittleRepository.count());
 30     }
 31 
 32     @Test
 33     @Transactional
 34     public void findRecent() {
 35         // default case
 36         {
 37             List<Spittle> recent = spittleRepository.findRecent();
 38             assertRecent(recent, 10);
 39         }
 40         
 41         // specific count case
 42         {
 43             List<Spittle> recent = spittleRepository.findRecent(5);
 44             assertRecent(recent, 5);
 45         }
 46     }
 47 
 48     @Test
 49     @Transactional
 50     public void findOne() {
 51         Spittle thirteen = spittleRepository.findOne(13);
 52         assertEquals(13, thirteen.getId().longValue());
 53         assertEquals("Bonjour from Art!", thirteen.getMessage());
 54         assertEquals(1332682500000L, thirteen.getPostedTime().getTime());
 55         assertEquals(4, thirteen.getSpitter().getId().longValue());
 56         assertEquals("artnames", thirteen.getSpitter().getUsername());
 57         assertEquals("password", thirteen.getSpitter().getPassword());
 58         assertEquals("Art Names", thirteen.getSpitter().getFullName());
 59         assertEquals("art@habuma.com", thirteen.getSpitter().getEmail());
 60         assertTrue(thirteen.getSpitter().isUpdateByEmail());
 61     }
 62 
 63     @Test
 64     @Transactional
 65     public void findBySpitter() {
 66         List<Spittle> spittles = spittleRepository.findBySpitterId(4L);
 67         assertEquals(11, spittles.size());
 68         for (int i = 0; i < 11; i++) {
 69             assertEquals(15-i, spittles.get(i).getId().longValue());
 70         }
 71     }
 72     
 73     @Test
 74     @Transactional
 75     public void save() {
 76         assertEquals(15, spittleRepository.count());
 77         Spitter spitter = spittleRepository.findOne(13).getSpitter();
 78         Spittle spittle = new Spittle(null, spitter, "Un Nuevo Spittle from Art", new Date());
 79         Spittle saved = spittleRepository.save(spittle);
 80         assertEquals(16, spittleRepository.count());
 81         assertNewSpittle(saved);
 82         assertNewSpittle(spittleRepository.findOne(16L));
 83     }
 84 
 85     @Test
 86     @Transactional
 87     public void delete() {
 88         assertEquals(15, spittleRepository.count());
 89         assertNotNull(spittleRepository.findOne(13));
 90         spittleRepository.delete(13L);
 91         assertEquals(14, spittleRepository.count());
 92         assertNull(spittleRepository.findOne(13));
 93     }
 94     
 95     private void assertRecent(List<Spittle> recent, int count) {
 96         long[] recentIds = new long[] {3,2,1,15,14,13,12,11,10,9};
 97         assertEquals(count, recent.size());
 98         for (int i = 0; i < count; i++) {
 99             assertEquals(recentIds[i], recent.get(i).getId().longValue());
100         }
101     }
102     
103     private void assertNewSpittle(Spittle spittle) {
104         assertEquals(16, spittle.getId().longValue());
105     }
106     
107 }
原文地址:https://www.cnblogs.com/shamgod/p/5344615.html