001/** 002 * Copyright 2005-2016 The Kuali Foundation 003 * 004 * Licensed under the Educational Community 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 * http://www.opensource.org/licenses/ecl2.php 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 */ 016package org.kuali.rice.krad.data; 017 018import org.kuali.rice.core.api.criteria.QueryByCriteria; 019import org.kuali.rice.core.api.criteria.QueryResults; 020import org.kuali.rice.krad.data.metadata.MetadataRepository; 021import org.springframework.dao.DataAccessException; 022import org.springframework.dao.IncorrectResultSizeDataAccessException; 023 024/** 025 * The primary API for interacting with the data layer. 026 * 027 * <p>Contains basic data access and query operations for supported data objects. Also provides access to the 028 * {@link MetadataRepository} which contains information about the structure and relationships between data objects.</p> 029 * 030 * <p>This service supports the ability to create a {@link DataObjectWrapper} for a given data object. This 031 * wrapper allows for accessing and manipulating properties within the data object as well as performing various 032 * metadata-aware operations on the data object.</p> 033 * 034 * <p>This service is meant to act as a facade to specific persistence and query-capable solutions and data stores. 035 * Implementations of this service may provide transactional capabilities where it makes sense to do so (and depending 036 * on the transactional support of the backend persistence technology). The documentation for the specific 037 * implementation of DataObjectService that is being used should be consulted for specifics on transaction 038 * semantics.</p> 039 * 040 * @author Kuali Rice Team (rice.collab@kuali.org) 041 */ 042public interface DataObjectService { 043 044 /** 045 * Invoked to retrieve a data object instance by a single primary key field or id object. In the 046 * case of a compound primary key consisting of multiple attributes on the data object, a 047 * {@link CompoundKey} can be passed in order to encapsulate these into a single argument. 048 * 049 * @param type the type of the data object to find 050 * @param id the id representing the primary key of the data object to find 051 * @param <T> the data object class type 052 * 053 * @return the entity with the given primary key or null if none found 054 * 055 * @throws IllegalArgumentException if {@code type} does not denote a data object type or {@code id} is not a valid 056 * type for the data object's primary key or is null 057 * @throws DataAccessException if data access fails 058 * 059 * @see CompoundKey 060 */ 061 <T> T find(Class<T> type, Object id); 062 063 /** 064 * Executes a query for the given data object. If the given QueryByCriteria is empty or null, then 065 * all data objects for the given type will be returned. Depending on the given criteria and the 066 * implementation for the query execution, not all matching results may be returned. The QueryResults 067 * will contain information on whether or not there are additional results which can be used for paging 068 * and similar functionality. 069 * 070 * @param type the type of the data objects to query 071 * @param queryByCriteria query object, can contain sorting and page request configuration 072 * @param <T> the data object class type 073 * 074 * @return the results of the query, will never return null but may return empty results 075 * 076 * @throws IllegalArgumentException if {@code type} does not denote a data object type, also if the 077 * {@code queryByCriteria} is null or empty. 078 * @throws DataAccessException if data access fails 079 */ 080 <T> QueryResults<T> findMatching(Class<T> type, QueryByCriteria queryByCriteria); 081 082 /** 083 * Executes a query for the given data object returning all data objects for the given type. 084 * 085 * @param type tye type of data objects to query 086 * @param <T> the data object class type 087 * 088 * @return the results of the query, will never return null but may return empty results. 089 * 090 * @throws IllegalArgumentException if {@code type} is null. 091 * @throws DataAccessException if data access fails. 092 */ 093 <T> QueryResults<T> findAll(Class<T> type); 094 095 /** 096 * Executes a query for the data object matching the given queryByCriteria and expecting a single unique result to 097 * be returned. If no results match the given criteria, then null will be returned. If the given criteria matches 098 * more than one result, then an {@link IncorrectResultSizeDataAccessException} will be 099 * thrown. 100 * 101 * @param type the type of the data object to query 102 * @param queryByCriteria query object defining the criteria for the query 103 * @param <T> the data object class type 104 * 105 * @return the single result of the query, or null if no objects were matched 106 * 107 * @throws IllegalArgumentException if {@code type} does not denote a data object type 108 * @throws IncorrectResultSizeDataAccessException if more than one object matched the given criteria 109 */ 110 <T> T findUnique(Class<T> type, QueryByCriteria queryByCriteria); 111 112 /** 113 * Deletes a given data object. 114 * 115 * @param dataObject the data object to delete 116 * 117 * @throws IllegalArgumentException if {@code dataObject} is not a valid data object 118 * @throws DataAccessException if data access fails 119 */ 120 void delete(Object dataObject); 121 122 /** 123 * Deletes records for the given type and matching the given criteria. If the given type is null then an 124 * IllegalArgumentException will be thrown. If the given criteria is null or empty an IllegalArgumentException 125 * is also thrown to help prevent table truncations. 126 * 127 * @param type the type of data objects to delete 128 * @param queryByCriteria query object 129 * 130 * @throws IllegalArgumentException if {@code type} is null or if the {@code QueryByCriteria} is null or empty 131 * @throws DataAccessException if data access fails 132 */ 133 <T> void deleteMatching(Class<T> type, QueryByCriteria queryByCriteria); 134 135 /** 136 * Removes all records for the given data object type 137 * 138 * @param type the type of data objects 139 * @param <T> the data object class type. 140 * 141 * @throws IllegalArgumentException if {@code type} is null 142 * @throws DataAccessException if data access fails 143 */ 144 <T> void deleteAll(Class<T> type); 145 146 /** 147 * Saves the given data object, determining whether or not this is a new data object which is being created, or an 148 * existing one which should be updated. 149 * 150 * <p>Optional persistence options can be passed to indicate whether or not linking should be performed prior to 151 * persistence. By default, linking is performed.</p> 152 * 153 * @param dataObject the data object to save 154 * @param options the options to use when saving the data object 155 * @param <T> the data object class type 156 * 157 * @return the saved data object, calling code should always use the reference the object returned from this method 158 * for future operations after calling the save since it could have been updated 159 * 160 * @throws IllegalArgumentException if {@code dataObject} is not a valid data object 161 * @throws DataAccessException if data access fails 162 */ 163 <T> T save(T dataObject, PersistenceOption... options); 164 165 /** 166 * Flushes any outstanding work to the backend data store. 167 * 168 * <p>Depending on the backend persistence implementation for the given type, this method may or may not do 169 * anything.</p> 170 * 171 * @param type the type of the data object for which to perform the flush. This is primarily used to identify the 172 * context in which to perform the flush. 173 */ 174 void flush(Class<?> type); 175 176 177 /** 178 * Returns the MetadataRepository which provides access to all data object metadata known to the system. 179 * 180 * @return the MetadataRepository 181 */ 182 MetadataRepository getMetadataRepository(); 183 184 /** 185 * Wraps the given data object in an accessor which provides numerous utility and helper methods related to 186 * accessing data and attributes on the data object. 187 * 188 * @param dataObject the data object to wrap, must be non-null 189 * @param <T> the type of the data object 190 * 191 * @return an accessor which wraps the given data object and it's associated metadata and provides utility and 192 * methods useful when accessing data and attributes on the data object 193 * 194 * @throws IllegalArgumentException if the given data object is null or an invalid data object type 195 */ 196 <T> DataObjectWrapper<T> wrap(T dataObject); 197 198 /** 199 * Returns a copy of the given data object instance. 200 * 201 * <p>The method of copying is provider dependent, and will handle instances (including nested) using whatever 202 * measures might be required to deal with the quirks of said provider (e.g. fetching lazy loaded relations). 203 * </p> 204 * 205 * @param dataObject the data object to copy 206 * @param <T> the type of the data object 207 * 208 * @return a copy of the given data object 209 */ 210 <T> T copyInstance(T dataObject, CopyOption... options); 211 212 /** 213 * Returns whether the DataObjectService supports the given type, where 214 * "supports" means that there is at least one PersistenceProvider that handles the given type. 215 * 216 * @param type the data object type 217 * 218 * @return whether the DataObjectService supports the given type 219 */ 220 <T> boolean supports(Class<T> type); 221 222}