001/* 002 * Copyright 2006-2013 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.batch.core; 018 019import java.io.Serializable; 020 021import org.springframework.util.ClassUtils; 022 023/** 024 * Batch Domain Entity class. Any class that should be uniquely identifiable 025 * from another should subclass from Entity. More information on this pattern 026 * and the difference between Entities and Value Objects can be found in Domain 027 * Driven Design by Eric Evans. 028 * 029 * @author Lucas Ward 030 * @author Dave Syer 031 * 032 */ 033@SuppressWarnings("serial") 034public class Entity implements Serializable { 035 036 private Long id; 037 038 private volatile Integer version; 039 040 public Entity() { 041 super(); 042 } 043 044 public Entity(Long id) { 045 super(); 046 047 //Commented out because StepExecutions are still created in a disconnected 048 //manner. The Repository should create them, then this can be uncommented. 049 //Assert.notNull(id, "Entity id must not be null."); 050 this.id = id; 051 } 052 053 public Long getId() { 054 return id; 055 } 056 057 public void setId(Long id) { 058 this.id = id; 059 } 060 061 /** 062 * @return the version 063 */ 064 public Integer getVersion() { 065 return version; 066 } 067 068 /** 069 * Public setter for the version needed only by repository methods. 070 * @param version the version to set 071 */ 072 public void setVersion(Integer version) { 073 this.version = version; 074 } 075 076 /** 077 * Increment the version number 078 */ 079 public void incrementVersion() { 080 if (version == null) { 081 version = 0; 082 } else { 083 version = version + 1; 084 } 085 } 086 087 @Override 088 public String toString() { 089 return String.format("%s: id=%d, version=%d", ClassUtils.getShortName(getClass()), id, version); 090 } 091 092 /** 093 * Attempt to establish identity based on id if both exist. If either id 094 * does not exist use Object.equals(). 095 * 096 * @see java.lang.Object#equals(java.lang.Object) 097 */ 098 @Override 099 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}