Hibernate使用二级缓存进行不必要的SELECT

时间:2015-07-07 10:02:56

标签: hibernate jpa spring-data-jpa ehcache jpa-2.1

在TestApplication类中,我使用由Hibernate支持的Spring Data JPA存储库将JPA实体保存3次,并配置了二级缓存。

在第一次保存时,Hibernate会发出一个SQL INSERT。 在第二次保存时,Hibernate发出两个SQL查询:SELECT和UPDATE。 最后,在第三次保存时,Hibernate只发出一个SQL UPDATE。

为什么在第二次保存期间我有SELECT查询? 第一次保存后,实体应该已经在二级缓存中,第二次保存应该像第三次保存一样。

Test.java:

@Entity
@Cacheable
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public class Test {
    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String value;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }    
}

TestRepository.java:

public interface TestRepository extends JpaRepository<Test, Long> {
}

TestApplication.java:

@SpringBootApplication
public class TestApplication {
    private static final Logger LOGGER = LoggerFactory.getLogger(TestApplication.class);

    public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext configurableApplicationContext = SpringApplication.run(TestApplication.class, args);
        TestRepository testRepository = configurableApplicationContext.getBean(TestRepository.class);

        Test test = new Test();
        test.setValue("test1");
        LOGGER.info("Save 1");
        testRepository.save(test);

        test.setValue("test2");
        LOGGER.info("Save 2");
        testRepository.save(test);

        test.setValue("test3");
        LOGGER.info("Save 3");
        testRepository.save(test);
    }
}

application.properties

logging.level.org.hibernate.SQL=DEBUG
spring.jpa.database: H2
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory

的pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.5.RELEASE</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-ehcache</artifactId>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
    </dependency>
</dependencies>

运行日志:

2015-07-07 10:53:33.865  INFO 3220 --- [           main] fr.test.TestApplication                  : Save 1
2015-07-07 10:53:33.950 DEBUG 3220 --- [           main] org.hibernate.SQL                        : insert into test (id, value) values (null, ?)
2015-07-07 10:53:34.002  INFO 3220 --- [           main] fr.test.TestApplication                  : Save 2
2015-07-07 10:53:34.029 DEBUG 3220 --- [           main] org.hibernate.SQL                        : select test0_.id as id1_0_0_, test0_.value as value2_0_0_ from test test0_ where test0_.id=?
2015-07-07 10:53:34.083 DEBUG 3220 --- [           main] org.hibernate.SQL                        : update test set value=? where id=?
2015-07-07 10:53:34.094  INFO 3220 --- [           main] fr.test.TestApplication                  : Save 3
2015-07-07 10:53:34.097 DEBUG 3220 --- [           main] org.hibernate.SQL                        : update test set value=? where id=?

0 个答案:

没有答案