1 /* 2 * Copyright 2006-2013 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 17 package org.springframework.batch.core; 18 19 import java.io.Serializable; 20 21 import org.springframework.util.ClassUtils; 22 23 /** 24 * Batch Domain Entity class. Any class that should be uniquely identifiable 25 * from another should subclass from Entity. More information on this pattern 26 * and the difference between Entities and Value Objects can be found in Domain 27 * Driven Design by Eric Evans. 28 * 29 * @author Lucas Ward 30 * @author Dave Syer 31 * 32 */ 33 @SuppressWarnings("serial") 34 public class Entity implements Serializable { 35 36 private Long id; 37 38 private volatile Integer version; 39 40 public Entity() { 41 super(); 42 } 43 44 public Entity(Long id) { 45 super(); 46 47 //Commented out because StepExecutions are still created in a disconnected 48 //manner. The Repository should create them, then this can be uncommented. 49 //Assert.notNull(id, "Entity id must not be null."); 50 this.id = id; 51 } 52 53 public Long getId() { 54 return id; 55 } 56 57 public void setId(Long id) { 58 this.id = id; 59 } 60 61 /** 62 * @return the version 63 */ 64 public Integer getVersion() { 65 return version; 66 } 67 68 /** 69 * Public setter for the version needed only by repository methods. 70 * @param version the version to set 71 */ 72 public void setVersion(Integer version) { 73 this.version = version; 74 } 75 76 /** 77 * Increment the version number 78 */ 79 public void incrementVersion() { 80 if (version == null) { 81 version = 0; 82 } else { 83 version = version + 1; 84 } 85 } 86 87 @Override 88 public String toString() { 89 return String.format("%s: id=%d, version=%d", ClassUtils.getShortName(getClass()), id, version); 90 } 91 92 /** 93 * Attempt to establish identity based on id if both exist. If either id 94 * does not exist use Object.equals(). 95 * 96 * @see java.lang.Object#equals(java.lang.Object) 97 */ 98 @Override 99 public boolean equals(Object other) { 100 if (other == this) { 101 return true; 102 } 103 if (other == null) { 104 return false; 105 } 106 if (!(other instanceof Entity)) { 107 return false; 108 } 109 Entity entity = (Entity) other; 110 if (id == null || entity.getId() == null) { 111 return false; 112 } 113 return id.equals(entity.getId()); 114 } 115 116 /** 117 * Use ID if it exists to establish hash code, otherwise fall back to 118 * Object.hashCode(). Based on the same information as equals, so if that 119 * changes, this will. N.B. this follows the contract of Object.hashCode(), 120 * but will cause problems for anyone adding an unsaved {@link Entity} to a 121 * Set because Set.contains() will almost certainly return false for the 122 * {@link Entity} after it is saved. Spring Batch does not store any of its 123 * entities in Sets as a matter of course, so internally this is consistent. 124 * Clients should not be exposed to unsaved entities. 125 * 126 * @see java.lang.Object#hashCode() 127 */ 128 @Override 129 public int hashCode() { 130 if (id == null) { 131 return super.hashCode(); 132 } 133 return 39 + 87 * id.hashCode(); 134 } 135 136 }