Skip to content

Commit 5852cc2

Browse files
committed
Add support for fluent findBy(…) query by example support.
Including projection and stream query support. Closes #2150 Original pull request: #2151.
1 parent 54feba9 commit 5852cc2

File tree

3 files changed

+445
-21
lines changed

3 files changed

+445
-21
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Copyright 2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.redis.repository.support;
17+
18+
import org.springframework.core.convert.converter.Converter;
19+
import org.springframework.data.mapping.PersistentEntity;
20+
import org.springframework.data.mapping.PersistentProperty;
21+
import org.springframework.data.mapping.PersistentPropertyAccessor;
22+
import org.springframework.data.mapping.PreferredConstructor;
23+
import org.springframework.data.mapping.PreferredConstructor.Parameter;
24+
import org.springframework.data.mapping.SimplePropertyHandler;
25+
import org.springframework.data.mapping.context.MappingContext;
26+
import org.springframework.data.mapping.model.EntityInstantiator;
27+
import org.springframework.data.mapping.model.EntityInstantiators;
28+
import org.springframework.data.mapping.model.ParameterValueProvider;
29+
import org.springframework.data.redis.core.mapping.RedisPersistentEntity;
30+
import org.springframework.data.redis.core.mapping.RedisPersistentProperty;
31+
import org.springframework.util.Assert;
32+
33+
/**
34+
* {@link Converter} to instantiate DTOs from fully equipped domain objects.
35+
*
36+
* @author Mark Paluch
37+
*/
38+
class DtoInstantiatingConverter implements Converter<Object, Object> {
39+
40+
private final Class<?> targetType;
41+
private final MappingContext<? extends PersistentEntity<?, ?>, ? extends PersistentProperty<?>> context;
42+
private final EntityInstantiator instantiator;
43+
44+
/**
45+
* Creates a new {@link Converter} to instantiate DTOs.
46+
*
47+
* @param dtoType must not be {@literal null}.
48+
* @param context must not be {@literal null}.
49+
* @param entityInstantiators must not be {@literal null}.
50+
*/
51+
public DtoInstantiatingConverter(Class<?> dtoType,
52+
MappingContext<? extends RedisPersistentEntity<?>, RedisPersistentProperty> context,
53+
EntityInstantiators entityInstantiators) {
54+
55+
Assert.notNull(dtoType, "DTO type must not be null!");
56+
Assert.notNull(context, "MappingContext must not be null!");
57+
Assert.notNull(entityInstantiators, "EntityInstantiators must not be null!");
58+
59+
this.targetType = dtoType;
60+
this.context = context;
61+
this.instantiator = entityInstantiators.getInstantiatorFor(context.getRequiredPersistentEntity(dtoType));
62+
}
63+
64+
/*
65+
* (non-Javadoc)
66+
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
67+
*/
68+
@Override
69+
@SuppressWarnings({ "rawtypes", "unchecked" })
70+
public Object convert(Object source) {
71+
72+
if (targetType.isInterface()) {
73+
return source;
74+
}
75+
76+
PersistentEntity<?, ?> sourceEntity = context.getRequiredPersistentEntity(source.getClass());
77+
PersistentPropertyAccessor sourceAccessor = sourceEntity.getPropertyAccessor(source);
78+
PersistentEntity<?, ?> targetEntity = context.getRequiredPersistentEntity(targetType);
79+
PreferredConstructor<?, ? extends PersistentProperty<?>> constructor = targetEntity.getPersistenceConstructor();
80+
81+
Object dto = instantiator.createInstance(targetEntity, new ParameterValueProvider() {
82+
83+
@Override
84+
public Object getParameterValue(Parameter parameter) {
85+
return sourceAccessor.getProperty(sourceEntity.getPersistentProperty(parameter.getName()));
86+
}
87+
});
88+
89+
PersistentPropertyAccessor dtoAccessor = targetEntity.getPropertyAccessor(dto);
90+
91+
targetEntity.doWithProperties((SimplePropertyHandler) property -> {
92+
93+
if (constructor.isConstructorParameter(property)) {
94+
return;
95+
}
96+
97+
dtoAccessor.setProperty(property,
98+
sourceAccessor.getProperty(sourceEntity.getPersistentProperty(property.getName())));
99+
});
100+
101+
return dto;
102+
}
103+
}

0 commit comments

Comments
 (0)