|
17 | 17 |
|
18 | 18 | import jakarta.persistence.IdClass;
|
19 | 19 | import jakarta.persistence.PersistenceUnitUtil;
|
| 20 | +import jakarta.persistence.Tuple; |
20 | 21 | import jakarta.persistence.metamodel.Attribute;
|
21 | 22 | import jakarta.persistence.metamodel.EntityType;
|
22 | 23 | import jakarta.persistence.metamodel.IdentifiableType;
|
|
34 | 35 | import java.util.Map;
|
35 | 36 | import java.util.Optional;
|
36 | 37 | import java.util.Set;
|
| 38 | +import java.util.function.Function; |
37 | 39 |
|
38 | 40 | import org.springframework.beans.BeanWrapper;
|
39 | 41 | import org.springframework.core.annotation.AnnotationUtils;
|
@@ -154,6 +156,11 @@ public ID getId(T entity) {
|
154 | 156 |
|
155 | 157 | // If it's a simple type, then immediately delegate to the provider
|
156 | 158 | if (idMetadata.hasSimpleId()) {
|
| 159 | + |
| 160 | + if (entity instanceof Tuple t) { |
| 161 | + return (ID) t.get(idMetadata.getSimpleIdAttribute().getName()); |
| 162 | + } |
| 163 | + |
157 | 164 | return (ID) persistenceUnitUtil.getIdentifier(entity);
|
158 | 165 | }
|
159 | 166 |
|
@@ -225,27 +232,38 @@ public boolean isNew(T entity) {
|
225 | 232 | @Override
|
226 | 233 | public Map<String, Object> getKeyset(Iterable<String> propertyPaths, T entity) {
|
227 | 234 |
|
228 |
| - // TODO: Proxy handling requires more elaborate refactoring, see |
229 |
| - // https://github.com/spring-projects/spring-data-jpa/issues/2784 |
230 |
| - BeanWrapper entityWrapper = new DirectFieldAccessFallbackBeanWrapper(entity); |
| 235 | + Function<String, Object> getter = getPropertyValueFunction(entity); |
231 | 236 |
|
232 | 237 | Map<String, Object> keyset = new LinkedHashMap<>();
|
233 | 238 |
|
234 | 239 | if (hasCompositeId()) {
|
235 | 240 | for (String idAttributeName : getIdAttributeNames()) {
|
236 |
| - keyset.put(idAttributeName, entityWrapper.getPropertyValue(idAttributeName)); |
| 241 | + keyset.put(idAttributeName, getter.apply(idAttributeName)); |
237 | 242 | }
|
238 | 243 | } else {
|
239 | 244 | keyset.put(getIdAttribute().getName(), getId(entity));
|
240 | 245 | }
|
241 | 246 |
|
242 | 247 | for (String propertyPath : propertyPaths) {
|
243 |
| - keyset.put(propertyPath, entityWrapper.getPropertyValue(propertyPath)); |
| 248 | + keyset.put(propertyPath, getter.apply(propertyPath)); |
244 | 249 | }
|
245 | 250 |
|
246 | 251 | return keyset;
|
247 | 252 | }
|
248 | 253 |
|
| 254 | + private Function<String, Object> getPropertyValueFunction(Object entity) { |
| 255 | + |
| 256 | + if (entity instanceof Tuple t) { |
| 257 | + return t::get; |
| 258 | + } |
| 259 | + |
| 260 | + // TODO: Proxy handling requires more elaborate refactoring, see |
| 261 | + // https://github.com/spring-projects/spring-data-jpa/issues/2784 |
| 262 | + BeanWrapper entityWrapper = new DirectFieldAccessFallbackBeanWrapper(entity); |
| 263 | + |
| 264 | + return entityWrapper::getPropertyValue; |
| 265 | + } |
| 266 | + |
249 | 267 | /**
|
250 | 268 | * Simple value object to encapsulate id specific metadata.
|
251 | 269 | *
|
|
0 commit comments