Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

DATAMONGO-279 - optimistic locking based on version field #11

Closed
wants to merge 2 commits into from

2 participants

Patryk Wasik Oliver Gierke
Patryk Wasik

This pull request contains optimistic locking implementation based on version field.

Changes:

added Version annotation with points to a version field
change save method on MongoTemplet to detect first time save or update.
If first save occure ((isNew() == true) and entity contains version filed then set this field to 0 and perform normal save.
If update occure (isNew() == false) then perform update with query by id and version and inc(version filed by one), then check writeConcern.getN() and throw OptimisticLockingFailureException if no documents was updated.

Any comments will be welcome.

Oliver Gierke

Very cool stuff. A tiny thing though: would you mind adding some code that binds the updated version to the current entity? Currently you have to manually load the entity to see the updated version number.

Another thought: would it make sense to update the version property in our code and then du a plain update with the former version constraint? That would solve the binding issue of the new version and probably simplify the construction of the update object a little as you don't have to add an inc(…) operation and manually exclude the version property from the update. As we change a single document only, the operation should be atomic anyway.

Patryk Wasik

Change completed.
Hope we don't go over long value in version :)
or do you have any other incrementation solution ?

Oliver Gierke

That looks pretty good now. I'll have a detailled look tomorrow, brush it up and might even integrate it already. Would make a nice a addition to the upcoming GA release. Would you mind filling out the contributors agreement and comment the id you get assigned? Thanks a ton already!

Patryk Wasik

My confirmation number is: 33320120907012713

Oliver Gierke

What's your name actually? Need it to polish up the JavaDoc (author tags etc.).

Patryk Wasik

Ah ok, I updated my account info. So it is Patryk Wasik.

Oliver Gierke

Polished and merged into master to be included in 1.1 GA. I've removed the MongoOperations enhancements and inlined the modified update(…) method. Added event triggering according to the ones used to from doSave(…).

Oliver Gierke olivergierke closed this September 11, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.

Showing 14 changed files with 312 additions and 5 deletions. Show diff stats Hide diff stats

  1. 2  spring-data-mongodb/pom.xml
  2. 2  spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java
  3. 45  spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java
  4. 32  ...ng-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java
  5. 8  ...-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java
  6. 4  spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentEntity.java
  7. 9  spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentProperty.java
  8. 21  spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/SimpleMongoMappingContext.java
  9. 18  spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/Version.java
  10. 14  spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java
  11. 26  ...ng-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoEntityInformation.java
  12. 31  ...ongodb/src/main/java/org/springframework/data/mongodb/repository/support/MappingMongoEntityInformation.java
  13. 37  spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java
  14. 68  ...ata-mongodb/src/test/java/org/springframework/data/mongodb/core/PersonWithVersionPropertyOfTypeInteger.java
2  spring-data-mongodb/pom.xml
@@ -181,7 +181,7 @@
181 181
 			<plugin>
182 182
 				<groupId>com.mysema.maven</groupId>
183 183
 				<artifactId>maven-apt-plugin</artifactId>
184  
-				<version>1.0.2</version>
  184
+				<version>1.0.4</version>
185 185
 				<executions>
186 186
 					<execution>
187 187
 						<phase>generate-test-sources</phase>
2  spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoOperations.java
@@ -657,6 +657,8 @@
657 657
 	 * @return the WriteResult which lets you access the results of the previous write.
658 658
 	 */
659 659
 	WriteResult updateFirst(Query query, Update update, Class<?> entityClass);
  660
+	
  661
+	WriteResult updateFirst(Query query, Object object, Class<?> entityClass);
660 662
 
661 663
 	/**
662 664
 	 * Updates the first object that is found in the specified collection that matches the query document criteria with
45  spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MongoTemplate.java
@@ -44,6 +44,7 @@
44 44
 import org.springframework.dao.DataAccessException;
45 45
 import org.springframework.dao.DataIntegrityViolationException;
46 46
 import org.springframework.dao.InvalidDataAccessApiUsageException;
  47
+import org.springframework.dao.OptimisticLockingFailureException;
47 48
 import org.springframework.data.authentication.UserCredentials;
48 49
 import org.springframework.data.convert.EntityReader;
49 50
 import org.springframework.data.mapping.PersistentEntity;
@@ -703,7 +704,31 @@ public void save(Object objectToSave) {
703 704
 	}
704 705
 
705 706
 	public void save(Object objectToSave, String collectionName) {
706  
-		doSave(collectionName, objectToSave, this.mongoConverter);
  707
+		 MongoPersistentEntity<?> mongoPersistentEntity = getPersistentEntity(objectToSave.getClass());
  708
+		 if(mongoPersistentEntity.hasVersion()){
  709
+			 BeanWrapper<PersistentEntity<Object,?>, Object> beanWrapper = BeanWrapper.create(objectToSave, this.mongoConverter.getConversionService());
  710
+			 Object id = beanWrapper.getProperty(mongoPersistentEntity.getIdProperty());
  711
+			 if(id == null){
  712
+				beanWrapper.setProperty(mongoPersistentEntity.getVersionProperty(), 0);
  713
+				doSave(collectionName, objectToSave, this.mongoConverter);
  714
+			 } else {
  715
+				 Query query = getUpdateVersionQuery(id,
  716
+						 beanWrapper.getProperty(mongoPersistentEntity.getVersionProperty()),mongoPersistentEntity);
  717
+				 
  718
+				 Number number = (Number) beanWrapper.getProperty(mongoPersistentEntity.getVersionProperty());
  719
+				 beanWrapper.setProperty(mongoPersistentEntity.getVersionProperty(), number.longValue()+1);
  720
+				 
  721
+				 updateFirst( query,
  722
+						 	objectToSave, objectToSave.getClass());
  723
+			 }
  724
+		 } else {
  725
+			 doSave(collectionName, objectToSave, this.mongoConverter);
  726
+		 }
  727
+	}
  728
+	
  729
+	private Query getUpdateVersionQuery(Object id, Object version,MongoPersistentEntity<?> mongoPersistentEntity) {
  730
+		return new Query( Criteria.where(mongoPersistentEntity.getIdProperty().getName()).is(id)
  731
+				.and(mongoPersistentEntity.getVersionProperty().getName()).is(version));
707 732
 	}
708 733
 
709 734
 	protected <T> void doSave(String collectionName, T objectToSave, MongoWriter<T> writer) {
@@ -816,6 +841,16 @@ public WriteResult updateFirst(Query query, Update update, Class<?> entityClass)
816 841
 	public WriteResult updateFirst(final Query query, final Update update, final String collectionName) {
817 842
 		return doUpdate(collectionName, query, update, null, false, false);
818 843
 	}
  844
+	
  845
+	public WriteResult updateFirst(final Query query, final Object object,
  846
+			Class<?> entityClass) {
  847
+
  848
+		BasicDBObject dbObject = new BasicDBObject();
  849
+		this.mongoConverter.write(object, dbObject);
  850
+
  851
+		return doUpdate(determineCollectionName(entityClass), query,
  852
+				Update.fromDBObject(dbObject, ID), entityClass, false, false);
  853
+	}
819 854
 
820 855
 	public WriteResult updateMulti(Query query, Update update, Class<?> entityClass) {
821 856
 		return doUpdate(determineCollectionName(entityClass), query, update, entityClass, false, true);
@@ -835,9 +870,10 @@ public WriteResult doInCollection(DBCollection collection) throws MongoException
835 870
 
836 871
 				DBObject queryObj = query == null ? new BasicDBObject()
837 872
 						: mapper.getMappedObject(query.getQueryObject(), entity);
  873
+
838 874
 				DBObject updateObj = update == null ? new BasicDBObject() : mapper.getMappedObject(update.getUpdateObject(),
839 875
 						entity);
840  
-
  876
+				
841 877
 				if (LOGGER.isDebugEnabled()) {
842 878
 					LOGGER.debug("calling update using query: " + queryObj + " and update: " + updateObj + " in collection: "
843 879
 							+ collectionName);
@@ -852,6 +888,11 @@ public WriteResult doInCollection(DBCollection collection) throws MongoException
852 888
 				} else {
853 889
 					wr = collection.update(queryObj, updateObj, upsert, multi, writeConcernToUse);
854 890
 				}
  891
+				if(null != entity && entity.hasVersion() && !multi){
  892
+					if(wr.getN() == 0){
  893
+						throw new OptimisticLockingFailureException("Optimistic lock exception on saveing entity: "+updateObj.toMap().toString());
  894
+					}
  895
+				}
855 896
 				handleAnyWriteResultErrors(wr, queryObj, "update with '" + updateObj + "'");
856 897
 				return wr;
857 898
 			}
32  ...data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java
@@ -25,6 +25,7 @@
25 25
 import org.springframework.context.expression.BeanFactoryResolver;
26 26
 import org.springframework.data.mapping.PersistentEntity;
27 27
 import org.springframework.data.mapping.model.BasicPersistentEntity;
  28
+import org.springframework.data.mapping.model.MappingException;
28 29
 import org.springframework.data.mongodb.MongoCollectionUtils;
29 30
 import org.springframework.data.util.TypeInformation;
30 31
 import org.springframework.expression.Expression;
@@ -46,6 +47,8 @@
46 47
 	private final String collection;
47 48
 	private final SpelExpressionParser parser;
48 49
 	private final StandardEvaluationContext context;
  50
+	
  51
+	private MongoPersistentProperty versionProperty;
49 52
 
50 53
 	/**
51 54
 	 * Creates a new {@link BasicMongoPersistentEntity} with the given {@link TypeInformation}. Will default the
@@ -70,6 +73,25 @@ public BasicMongoPersistentEntity(TypeInformation<T> typeInformation) {
70 73
 			this.collection = fallback;
71 74
 		}
72 75
 	}
  76
+	
  77
+	/* 
  78
+	 * (non-Javadoc)
  79
+	 * @see org.springframework.data.mapping.MutablePersistentEntity#addPersistentProperty(P)
  80
+	 */
  81
+	@Override
  82
+	public void addPersistentProperty(MongoPersistentProperty property) {		
  83
+		if (property.isVersion()) {
  84
+			if (this.versionProperty != null) {
  85
+				throw new MappingException(
  86
+						String.format(
  87
+								"Attempt to add version property %s but already have property %s registered "
  88
+										+ "as version. Check your mapping configuration!",
  89
+								property.getField(), versionProperty.getField()));
  90
+			}
  91
+			this.versionProperty = property;
  92
+		}
  93
+		super.addPersistentProperty(property);
  94
+	}
73 95
 
74 96
 	/*
75 97
 	 * (non-Javadoc)
@@ -91,6 +113,14 @@ public String getCollection() {
91 113
 		Expression expression = parser.parseExpression(collection, ParserContext.TEMPLATE_EXPRESSION);
92 114
 		return expression.getValue(context, String.class);
93 115
 	}
  116
+	
  117
+	public MongoPersistentProperty getVersionProperty() {	
  118
+		return versionProperty;
  119
+	}
  120
+
  121
+	public boolean hasVersion() {	
  122
+		return getVersionProperty() != null;
  123
+	}
94 124
 
95 125
 	/**
96 126
 	 * {@link Comparator} implementation inspecting the {@link MongoPersistentProperty}'s order.
@@ -117,5 +147,5 @@ public int compare(MongoPersistentProperty o1, MongoPersistentProperty o2) {
117 147
 
118 148
 			return o1.getFieldOrder() - o2.getFieldOrder();
119 149
 		}
120  
-	}
  150
+	}	
121 151
 }
8  ...ta-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java
@@ -16,6 +16,7 @@
16 16
 package org.springframework.data.mongodb.core.mapping;
17 17
 
18 18
 import java.beans.PropertyDescriptor;
  19
+import java.io.ObjectInputStream.GetField;
19 20
 import java.lang.reflect.Field;
20 21
 import java.math.BigInteger;
21 22
 import java.util.HashSet;
@@ -142,4 +143,11 @@ public boolean isDbReference() {
142 143
 	public DBRef getDBRef() {
143 144
 		return getField().getAnnotation(DBRef.class);
144 145
 	}
  146
+
  147
+	/* (non-Javadoc)
  148
+	 * @see org.springframework.data.mongodb.core.core.mapping.MongoPersistentProperty#isVersion()
  149
+	 */
  150
+	public boolean isVersion() {		
  151
+		return getField().isAnnotationPresent(Version.class);
  152
+	}
145 153
 }
4  spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentEntity.java
@@ -9,4 +9,8 @@
9 9
 public interface MongoPersistentEntity<T> extends PersistentEntity<T, MongoPersistentProperty> {
10 10
 
11 11
 	String getCollection();
  12
+	
  13
+	MongoPersistentProperty getVersionProperty();
  14
+	
  15
+	boolean hasVersion();
12 16
 }
9  ...ng-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentProperty.java
@@ -54,6 +54,15 @@
54 54
 	 * @return
55 55
 	 */
56 56
 	DBRef getDBRef();
  57
+	
  58
+		
  59
+	/**
  60
+	 * Returns whether the property is {@link Version}. 
  61
+	 * 
  62
+	 * @return
  63
+	 */
  64
+	boolean isVersion();	
  65
+		
57 66
 
58 67
 	/**
59 68
 	 * Simple {@link Converter} implementation to transform a {@link MongoPersistentProperty} into its field name.
21  ...-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/SimpleMongoMappingContext.java
@@ -112,7 +112,15 @@ public boolean isDbReference() {
112 112
 		public DBRef getDBRef() {
113 113
 			return null;
114 114
 		}
115  
-	}
  115
+		
  116
+		/* (non-Javadoc)
  117
+		 * @see org.springframework.data.mongodb.core.core.mapping.MongoPersistentProperty#isVersion()
  118
+		 */
  119
+		public boolean isVersion() {
  120
+			return false;
  121
+		}
  122
+		
  123
+	} 
116 124
 
117 125
 	static class SimpleMongoPersistentEntity<T> extends BasicPersistentEntity<T, MongoPersistentProperty> implements
118 126
 			MongoPersistentEntity<T> {
@@ -130,5 +138,16 @@ public SimpleMongoPersistentEntity(TypeInformation<T> information) {
130 138
 		public String getCollection() {
131 139
 			return MongoCollectionUtils.getPreferredCollectionName(getType());
132 140
 		}
  141
+		
  142
+		/* (non-Javadoc)
  143
+		 * @see org.springframework.data.mongodb.core.core.mapping.MongoPersistentEntity#getVersionProperty()
  144
+		 */
  145
+		public MongoPersistentProperty getVersionProperty() {
  146
+			return null;
  147
+		}
  148
+
  149
+		public boolean hasVersion() {
  150
+			return false;
  151
+		}
133 152
 	}
134 153
 }
18  spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/Version.java
... ...
@@ -0,0 +1,18 @@
  1
+package org.springframework.data.mongodb.core.mapping;
  2
+
  3
+import java.lang.annotation.Documented;
  4
+import java.lang.annotation.Retention;
  5
+import java.lang.annotation.Target;
  6
+import static java.lang.annotation.ElementType.FIELD;
  7
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
  8
+
  9
+/**
  10
+ * Specifies the version field that serves as its optimistic lock value.
  11
+ *  
  12
+ */
  13
+@Documented
  14
+@Target({ FIELD })
  15
+@Retention(RUNTIME)
  16
+public @interface Version {
  17
+
  18
+}
14  spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Update.java
@@ -15,8 +15,10 @@
15 15
  */
16 16
 package org.springframework.data.mongodb.core.query;
17 17
 
  18
+import java.util.Arrays;
18 19
 import java.util.HashMap;
19 20
 import java.util.LinkedHashMap;
  21
+import java.util.List;
20 22
 
21 23
 import com.mongodb.BasicDBObject;
22 24
 import com.mongodb.DBObject;
@@ -39,6 +41,18 @@
39 41
 	public static Update update(String key, Object value) {
40 42
 		return new Update().set(key, value);
41 43
 	}
  44
+		
  45
+	public static Update fromDBObject(DBObject object, String... exclude) {
  46
+		Update update = new Update();
  47
+		List<String> excludeList = Arrays.asList(exclude);
  48
+		for (String key : object.keySet()) {	
  49
+			if(excludeList.contains(key)) {
  50
+				continue;
  51
+			}
  52
+			update.set(key, object.get(key));
  53
+		}		
  54
+		return update;
  55
+	}
42 56
 
43 57
 	/**
44 58
 	 * Update using the $set update modifier
26  ...data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoEntityInformation.java
@@ -39,4 +39,30 @@
39 39
 	 * @return
40 40
 	 */
41 41
 	String getIdAttribute();
  42
+	
  43
+	
  44
+	/**
  45
+	 * Returns the attribute that the version will be persisted to.
  46
+	 * 
  47
+	 * @return
  48
+	 */
  49
+	String getVersionAttribute();
  50
+	
  51
+	
  52
+	/**
  53
+	 * Returns the entity version.
  54
+	 * 
  55
+	 * @return
  56
+	 */
  57
+	Object getVersion(T entity);
  58
+	
  59
+	
  60
+	
  61
+	/**
  62
+	 * Returns whether entity has version. 
  63
+	 * 
  64
+	 * @param entity
  65
+	 * @return
  66
+	 */
  67
+	boolean hasVersion(T entity);
42 68
 }
31  ...odb/src/main/java/org/springframework/data/mongodb/repository/support/MappingMongoEntityInformation.java
@@ -71,6 +71,30 @@ public ID getId(T entity) {
71 71
 			throw new RuntimeException(e);
72 72
 		}
73 73
 	}
  74
+	
  75
+	/* (non-Javadoc)
  76
+	 * @see org.springframework.data.mongodb.repository.query.MongoEntityInformation#getVersion(T)
  77
+	 */
  78
+	public Object getVersion(T entity) {
  79
+		MongoPersistentProperty versionProperty = entityMetadata.getVersionProperty();
  80
+		try {
  81
+			return BeanWrapper.create(entity, null).getProperty(versionProperty);
  82
+		} catch (Exception e) {
  83
+			throw new RuntimeException(e);
  84
+		}
  85
+	}
  86
+	
  87
+	/* (non-Javadoc)
  88
+	 * @see org.springframework.data.mongodb.repository.query.MongoEntityInformation#hasVersion(T)
  89
+	 */
  90
+	public boolean hasVersion(T entity) {
  91
+		try {
  92
+			getVersion(entity);
  93
+			return true;
  94
+		} catch (Exception e) {
  95
+			return false;
  96
+		}
  97
+	}
74 98
 
75 99
 	/* (non-Javadoc)
76 100
 	 * @see org.springframework.data.repository.support.EntityInformation#getIdType()
@@ -93,4 +117,11 @@ public String getCollectionName() {
93 117
 	public String getIdAttribute() {
94 118
 		return entityMetadata.getIdProperty().getName();
95 119
 	}
  120
+	
  121
+	/* (non-Javadoc)
  122
+	 * @see org.springframework.data.mongodb.repository.MongoEntityInformation#getVersionAttribute()
  123
+	 */
  124
+	public String getVersionAttribute() {
  125
+		return entityMetadata.getVersionProperty().getName();
  126
+	}
96 127
 }
37  spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java
@@ -40,6 +40,7 @@
40 40
 import org.springframework.core.convert.converter.Converter;
41 41
 import org.springframework.dao.DataAccessException;
42 42
 import org.springframework.dao.DataIntegrityViolationException;
  43
+import org.springframework.dao.OptimisticLockingFailureException;
43 44
 import org.springframework.data.annotation.Id;
44 45
 import org.springframework.data.annotation.PersistenceConstructor;
45 46
 import org.springframework.data.mongodb.InvalidMongoDbApiUsageException;
@@ -134,6 +135,7 @@ protected void cleanDb() {
134 135
 		template.dropCollection(PersonWithIdPropertyOfPrimitiveInt.class);
135 136
 		template.dropCollection(PersonWithIdPropertyOfTypeLong.class);
136 137
 		template.dropCollection(PersonWithIdPropertyOfPrimitiveLong.class);
  138
+		template.dropCollection(PersonWithVersionPropertyOfTypeInteger.class);
137 139
 		template.dropCollection(TestClass.class);
138 140
 		template.dropCollection(Sample.class);
139 141
 		template.dropCollection(MyPerson.class);
@@ -1262,6 +1264,41 @@ public void exceutesBasicQueryCorrectly() {
1262 1264
 		assertThat(result, hasSize(1));
1263 1265
 		assertThat(result.get(0), hasProperty("name", is("Oleg")));
1264 1266
 	}
  1267
+	
  1268
+	@Test(expected = OptimisticLockingFailureException.class)
  1269
+	public void optimisticLockingHandling() {
  1270
+		
  1271
+		//Init version
  1272
+		PersonWithVersionPropertyOfTypeInteger person = new PersonWithVersionPropertyOfTypeInteger();
  1273
+		person.setAge(29);
  1274
+		person.setFirstName("Patryk");
  1275
+		template.save(person);
  1276
+		
  1277
+		List<PersonWithVersionPropertyOfTypeInteger> result = template.findAll(PersonWithVersionPropertyOfTypeInteger.class);
  1278
+		
  1279
+		assertThat(result, hasSize(1));
  1280
+		assertThat(result.get(0), hasProperty("version", is(0)));
  1281
+		
  1282
+		//Version change
  1283
+		person = result.get(0);
  1284
+		person.setFirstName("Patryk2");
  1285
+		
  1286
+		template.save(person);
  1287
+		
  1288
+		assertThat(person, hasProperty("version",is(1)));
  1289
+		
  1290
+		result = mappingTemplate.findAll(PersonWithVersionPropertyOfTypeInteger.class);
  1291
+		
  1292
+		assertThat(result, hasSize(1));
  1293
+		assertThat(result.get(0), hasProperty("version", is(1)));
  1294
+		
  1295
+		//Optimistic lock exception
  1296
+		person.setVersion(0);
  1297
+		person.setFirstName("Patryk3");
  1298
+		
  1299
+		template.save(person);
  1300
+		
  1301
+	}
1265 1302
 
1266 1303
 	static class MyId {
1267 1304
 
68  ...-mongodb/src/test/java/org/springframework/data/mongodb/core/PersonWithVersionPropertyOfTypeInteger.java
... ...
@@ -0,0 +1,68 @@
  1
+/*
  2
+ * Copyright 2010-2011 the original author or authors.
  3
+ *
  4
+ * Licensed under the Apache License, Version 2.0 (the "License");
  5
+ * you may not use this file except in compliance with the License.
  6
+ * You may obtain a copy of the License at
  7
+ *
  8
+ *      http://www.apache.org/licenses/LICENSE-2.0
  9
+ *
  10
+ * Unless required by applicable law or agreed to in writing, software
  11
+ * distributed under the License is distributed on an "AS IS" BASIS,
  12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13
+ * See the License for the specific language governing permissions and
  14
+ * limitations under the License.
  15
+ */
  16
+package org.springframework.data.mongodb.core;
  17
+
  18
+import org.springframework.data.mongodb.core.mapping.Version;
  19
+
  20
+public class PersonWithVersionPropertyOfTypeInteger {
  21
+
  22
+	private String id;
  23
+
  24
+	private String firstName;
  25
+
  26
+	private int age;
  27
+
  28
+	@Version
  29
+	private Integer version;
  30
+	
  31
+	public void setId(String id) {
  32
+		this.id = id;
  33
+	}
  34
+
  35
+	public String getId() {
  36
+		return id;
  37
+	}
  38
+	
  39
+	public String getFirstName() {
  40
+		return firstName;
  41
+	}
  42
+
  43
+	public void setFirstName(String firstName) {
  44
+		this.firstName = firstName;
  45
+	}
  46
+
  47
+	public int getAge() {
  48
+		return age;
  49
+	}
  50
+
  51
+	public void setAge(int age) {
  52
+		this.age = age;
  53
+	}
  54
+	
  55
+	public Integer getVersion() {
  56
+		return version;
  57
+	}
  58
+	
  59
+	public void setVersion(Integer version) {
  60
+		this.version = version;
  61
+	}
  62
+
  63
+	@Override
  64
+	public String toString() {
  65
+		return "PersonWithVersionPropertyOfTypeInteger [id=" + id + ", firstName=" + firstName + ", age=" + age +  ", version="+ version + "]";
  66
+	}
  67
+
  68
+}
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.