diff --git a/src/main/java/org/apache/ibatis/annotations/Options.java b/src/main/java/org/apache/ibatis/annotations/Options.java
index 671fa194706..fe7589ea367 100644
--- a/src/main/java/org/apache/ibatis/annotations/Options.java
+++ b/src/main/java/org/apache/ibatis/annotations/Options.java
@@ -29,9 +29,22 @@
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Options {
+ /**
+ * The options for the {@link Options#flushCache()}.
+ * The default is {@link FlushCachePolicy#DEFAULT}
+ */
+ public enum FlushCachePolicy {
+ /** false
for select statement; true
for insert/update/delete statement. */
+ DEFAULT,
+ /** Flushes cache regardless of the statement type. */
+ TRUE,
+ /** Does not flush cache regardless of the statement type. */
+ FALSE
+ }
+
boolean useCache() default true;
- boolean flushCache() default false;
+ FlushCachePolicy flushCache() default FlushCachePolicy.DEFAULT;
ResultSetType resultSetType() default ResultSetType.FORWARD_ONLY;
diff --git a/src/main/java/org/apache/ibatis/builder/annotation/MapperAnnotationBuilder.java b/src/main/java/org/apache/ibatis/builder/annotation/MapperAnnotationBuilder.java
index 9b4e1c27f9e..440a81274a8 100644
--- a/src/main/java/org/apache/ibatis/builder/annotation/MapperAnnotationBuilder.java
+++ b/src/main/java/org/apache/ibatis/builder/annotation/MapperAnnotationBuilder.java
@@ -55,6 +55,7 @@
import org.apache.ibatis.annotations.TypeDiscriminator;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.annotations.UpdateProvider;
+import org.apache.ibatis.annotations.Options.FlushCachePolicy;
import org.apache.ibatis.binding.BindingException;
import org.apache.ibatis.binding.MapperMethod.ParamMap;
import org.apache.ibatis.builder.BuilderException;
@@ -292,7 +293,11 @@ void parseStatement(Method method) {
}
if (options != null) {
- flushCache = options.flushCache();
+ if (FlushCachePolicy.TRUE.equals(options.flushCache())) {
+ flushCache = true;
+ } else if (FlushCachePolicy.FALSE.equals(options.flushCache())) {
+ flushCache = false;
+ }
useCache = options.useCache();
fetchSize = options.fetchSize() > -1 || options.fetchSize() == Integer.MIN_VALUE ? options.fetchSize() : null; //issue #348
timeout = options.timeout() > -1 ? options.timeout() : null;
diff --git a/src/site/es/xdoc/java-api.xml b/src/site/es/xdoc/java-api.xml
index 073e913f633..c003c884ab9 100644
--- a/src/site/es/xdoc/java-api.xml
+++ b/src/site/es/xdoc/java-api.xml
@@ -395,7 +395,7 @@ try (SqlSession session = sqlSessionFactory.openSession()) {
@Options
Method
Method
Options
アノテーションによって、各ステートメントのアノテーションを複雑化することなく、一貫したクリーンな方法で設定にアクセスできるよう工夫されています。キー: Attributes:
- useCache=true
, flushCache=false
, resultSetType=FORWARD_ONLY
,
+ useCache=true
, flushCache=FlushCachePolicy.DEFAULT
, resultSetType=FORWARD_ONLY
,
statementType=PREPARED
, fetchSize=-1
, timeout=-1
,
useGeneratedKeys=false
, keyProperty="id"
, keyColumn=""
.
Java アノテーションを使う場合、値として null
を指定することはできないという制限があります。これはどういうことかというと、Options
アノテーションを付加したステートメントにはデフォルトのオプションが適用されるということです。予期しない動作を防ぐため、各オプションのデフォルト値を把握しておくようにしてください。Options
annotation provides a consistent and clear way to access these. Attributes:
- useCache=true
, flushCache=false
, resultSetType=FORWARD_ONLY
,
+ useCache=true
, flushCache=FlushCachePolicy.DEFAULT
, resultSetType=FORWARD_ONLY
,
statementType=PREPARED
, fetchSize=-1
, timeout=-1
,
useGeneratedKeys=false
, keyProperty="id"
, keyColumn=""
.
It's important to understand that with Java Annotations, there is no way to specify null
as a value.
diff --git a/src/site/zh/xdoc/java-api.xml b/src/site/zh/xdoc/java-api.xml
index d76204a4592..150da96fe29 100644
--- a/src/site/zh/xdoc/java-api.xml
+++ b/src/site/zh/xdoc/java-api.xml
@@ -670,7 +670,7 @@ select,是映射语句(也就是映射器方
而不是将每条语句注解变复
杂,Options 注解提供连贯清晰的方式
来访问它们。属性:useCache=true ,
-flushCache=false
+flushCache=FlushCachePolicy.DEFAULT
,
resultSetType=FORWARD_ONLY ,
statementType=PREPARED ,
diff --git a/src/test/java/org/apache/ibatis/submitted/cache/CacheTest.java b/src/test/java/org/apache/ibatis/submitted/cache/CacheTest.java
index 361aaed7145..8c84a81233c 100644
--- a/src/test/java/org/apache/ibatis/submitted/cache/CacheTest.java
+++ b/src/test/java/org/apache/ibatis/submitted/cache/CacheTest.java
@@ -168,4 +168,96 @@ public void testplan3() {
}
}
+ /*-
+ * Test case for #405
+ *
+ * Test Plan with Autocommit on:
+ * 1) SqlSession 1 executes "select * from A".
+ * 2) SqlSession 1 closes.
+ * 3) SqlSession 2 executes "insert into person (id, firstname, lastname) values (3, hello, world)"
+ * 4) SqlSession 2 closes.
+ * 5) SqlSession 3 executes "select * from A".
+ * 6) SqlSession 3 closes.
+ *
+ * Assert:
+ * Step 5 returns 3 row.
+ */
+ @Test
+ public void shouldInsertWithOptionsFlushesCache() {
+ SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
+ try {
+ PersonMapper pm = sqlSession1.getMapper(PersonMapper.class);
+ Assert.assertEquals(2, pm.findAll().size());
+ } finally {
+ sqlSession1.close();
+ }
+
+ SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
+ try {
+ PersonMapper pm = sqlSession2.getMapper(PersonMapper.class);
+ Person p = new Person(3, "hello", "world");
+ pm.createWithOptions(p);
+ } finally {
+ sqlSession2.close();
+ }
+
+ SqlSession sqlSession3 = sqlSessionFactory.openSession(true);
+ try {
+ PersonMapper pm = sqlSession3.getMapper(PersonMapper.class);
+ Assert.assertEquals(3, pm.findAll().size());
+ } finally {
+ sqlSession3.close();
+ }
+ }
+
+ /*-
+ * Test Plan with Autocommit on:
+ * 1) SqlSession 1 executes select to cache result
+ * 2) SqlSession 1 closes.
+ * 3) SqlSession 2 executes insert without flushing cache
+ * 4) SqlSession 2 closes.
+ * 5) SqlSession 3 executes select (flushCache = false)
+ * 6) SqlSession 3 closes.
+ * 7) SqlSession 4 executes select (flushCache = true)
+ * 8) SqlSession 4 closes.
+ *
+ * Assert:
+ * Step 5 returns 2 row.
+ * Step 7 returns 3 row.
+ */
+ @Test
+ public void shouldApplyFlushCacheOptions() {
+ SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
+ try {
+ PersonMapper pm = sqlSession1.getMapper(PersonMapper.class);
+ Assert.assertEquals(2, pm.findAll().size());
+ } finally {
+ sqlSession1.close();
+ }
+
+ SqlSession sqlSession2 = sqlSessionFactory.openSession(true);
+ try {
+ PersonMapper pm = sqlSession2.getMapper(PersonMapper.class);
+ Person p = new Person(3, "hello", "world");
+ pm.createWithoutFlushCache(p);
+ } finally {
+ sqlSession2.close();
+ }
+
+ SqlSession sqlSession3 = sqlSessionFactory.openSession(true);
+ try {
+ PersonMapper pm = sqlSession3.getMapper(PersonMapper.class);
+ Assert.assertEquals(2, pm.findAll().size());
+ } finally {
+ sqlSession3.close();
+ }
+
+ SqlSession sqlSession4 = sqlSessionFactory.openSession(true);
+ try {
+ PersonMapper pm = sqlSession4.getMapper(PersonMapper.class);
+ Assert.assertEquals(3, pm.findWithFlushCache().size());
+ } finally {
+ sqlSession4.close();
+ }
+ }
}
diff --git a/src/test/java/org/apache/ibatis/submitted/cache/PersonMapper.java b/src/test/java/org/apache/ibatis/submitted/cache/PersonMapper.java
index 623f937be40..cbd71db723e 100644
--- a/src/test/java/org/apache/ibatis/submitted/cache/PersonMapper.java
+++ b/src/test/java/org/apache/ibatis/submitted/cache/PersonMapper.java
@@ -20,6 +20,8 @@
import org.apache.ibatis.annotations.CacheNamespace;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Options;
+import org.apache.ibatis.annotations.Options.FlushCachePolicy;
import org.apache.ibatis.annotations.Select;
@CacheNamespace
@@ -28,9 +30,21 @@ public interface PersonMapper {
@Insert("insert into person (id, firstname, lastname) values (#{id}, #{firstname}, #{lastname})")
public void create(Person person);
+ @Insert("insert into person (id, firstname, lastname) values (#{id}, #{firstname}, #{lastname})")
+ @Options
+ public void createWithOptions(Person person);
+
+ @Insert("insert into person (id, firstname, lastname) values (#{id}, #{firstname}, #{lastname})")
+ @Options(flushCache = FlushCachePolicy.FALSE)
+ public void createWithoutFlushCache(Person person);
+
@Delete("delete from person where id = #{id}")
public void delete(int id);
@Select("select id, firstname, lastname from person")
public List