001package io.ebean; 002 003import io.ebean.bean.EntityBean; 004 005import java.util.Collection; 006 007/** 008 * Provides finder functionality for use with "Dependency Injection style" use of Ebean. 009 * <p> 010 * <pre>{@code 011 * 012 * @Repository 013 * public class CustomerRepository extends BeanRepository<Long,Customer> { 014 * 015 * @Inject 016 * public CustomerRepository(Database server) { 017 * super(Customer.class, server); 018 * } 019 * 020 * // ... add customer specific finders and persist logic 021 * 022 * public List<Customer> findByName(String nameStart) { 023 * return query().where() 024 * .istartsWith("name", nameStart) 025 * .findList(); 026 * } 027 * 028 * } 029 * }</pre> 030 * 031 * @param <I> The ID type 032 * @param <T> The Bean type 033 */ 034public abstract class BeanRepository<I, T> extends BeanFinder<I, T> { 035 036 /** 037 * Create with the given bean type and Database instance. 038 * <p> 039 * Typically users would extend BeanRepository rather than BeanFinder. 040 * </p> 041 * <pre>{@code 042 * 043 * @Inject 044 * public CustomerRepository(Database server) { 045 * super(Customer.class, server); 046 * } 047 * 048 * }</pre> 049 * 050 * @param type The bean type 051 * @param server The Database instance typically created via Spring factory or equivalent 052 */ 053 protected BeanRepository(Class<T> type, Database server) { 054 super(type, server); 055 } 056 057 /** 058 * Marks the entity bean as dirty. 059 * <p> 060 * This is used so that when a bean that is otherwise unmodified is updated the version 061 * property is updated. 062 * <p> 063 * An unmodified bean that is saved or updated is normally skipped and this marks the bean as 064 * dirty so that it is not skipped. 065 * <p> 066 * <pre>{@code 067 * 068 * Customer customer = customerRepository.byId(id); 069 * 070 * // mark the bean as dirty so that a save() or update() will 071 * // increment the version property 072 * 073 * customerRepository.markAsDirty(customer); 074 * customerRepository.save(customer); 075 * 076 * }</pre> 077 * 078 * @see Database#markAsDirty(Object) 079 */ 080 public void markAsDirty(T bean) { 081 db().markAsDirty(bean); 082 } 083 084 /** 085 * Mark the property as unset or 'not loaded'. 086 * <p> 087 * This would be used to specify a property that we did not wish to include in a stateless update. 088 * </p> 089 * <pre>{@code 090 * 091 * // populate an entity bean from JSON or whatever 092 * Customer customer = ...; 093 * 094 * // mark the email property as 'unset' so that it is not 095 * // included in a 'stateless update' 096 * customerRepository.markPropertyUnset(customer, "email"); 097 * 098 * customerRepository.update(customer); 099 * 100 * }</pre> 101 * 102 * @param propertyName the name of the property on the bean to be marked as 'unset' 103 */ 104 public void markPropertyUnset(T bean, String propertyName) { 105 ((EntityBean) bean)._ebean_getIntercept().setPropertyLoaded(propertyName, false); 106 } 107 108 /** 109 * Insert or update this entity depending on its state. 110 * <p> 111 * Ebean will detect if this is a new bean or a previously fetched bean and perform either an 112 * insert or an update based on that. 113 * 114 * @see Database#save(Object) 115 */ 116 public void save(T bean) { 117 db().save(bean); 118 } 119 120 /** 121 * Save all the beans in the collection. 122 */ 123 public int saveAll(Collection<T> bean) { 124 return db().saveAll(bean); 125 } 126 127 /** 128 * Update this entity. 129 * 130 * @see Database#update(Object) 131 */ 132 public void update(T bean) { 133 db().update(bean); 134 } 135 136 /** 137 * Insert this entity. 138 * 139 * @see Database#insert(Object) 140 */ 141 public void insert(T bean) { 142 db().insert(bean); 143 } 144 145 /** 146 * Delete this bean. 147 * <p> 148 * This will return true if the bean was deleted successfully or JDBC batch is being used. 149 * </p> 150 * <p> 151 * If there is no current transaction one will be created and committed for 152 * you automatically. 153 * </p> 154 * <p> 155 * If the Bean does not have a version property (or loaded version property) and 156 * the bean does not exist then this returns false indicating that nothing was 157 * deleted. Note that, if JDBC batch mode is used then this always returns true. 158 * </p> 159 * 160 * @see Database#delete(Object) 161 */ 162 public boolean delete(T bean) { 163 return db().delete(bean); 164 } 165 166 /** 167 * Delete all the beans in the collection. 168 */ 169 public int deleteAll(Collection<T> beans) { 170 return db().deleteAll(beans); 171 } 172 173 /** 174 * Delete a bean permanently without soft delete. 175 * <p> 176 * This is used when the bean contains a <code>@SoftDelete</code> property and we 177 * want to perform a hard/permanent delete. 178 * </p> 179 * 180 * @see Database#deletePermanent(Object) 181 */ 182 public boolean deletePermanent(T bean) { 183 return db().deletePermanent(bean); 184 } 185 186 /** 187 * Merge this entity using the default merge options. 188 * <p> 189 * Ebean will detect if this is a new bean or a previously fetched bean and perform either an 190 * insert or an update based on that. 191 * 192 * @see Database#merge(Object) 193 */ 194 public void merge(T bean) { 195 db().merge(bean); 196 } 197 198 /** 199 * Merge this entity using the specified merge options. 200 * <p> 201 * Ebean will detect if this is a new bean or a previously fetched bean and perform either an 202 * insert or an update based on that. 203 * 204 * @see Database#merge(Object, MergeOptions) 205 */ 206 public void merge(T bean, MergeOptions options) { 207 db().merge(bean, options); 208 } 209 210 /** 211 * Refreshes this entity from the database. 212 * 213 * @see Database#refresh(Object) 214 */ 215 public void refresh(T bean) { 216 db().refresh(bean); 217 } 218}