|
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