Skip to content

Commit 10f6338

Browse files
committed
Add fluent API support for QuerydslKeyValueRepository.
Also reuse ProjectionFactory from repository factory. Closes #397.
1 parent b9b5aae commit 10f6338

File tree

5 files changed

+517
-33
lines changed

5 files changed

+517
-33
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
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.keyvalue.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.util.Assert;
30+
31+
/**
32+
* {@link Converter} to instantiate DTOs from fully equipped domain objects.
33+
*
34+
* @author Mark Paluch
35+
* @since 2.6
36+
*/
37+
class DtoInstantiatingConverter implements Converter<Object, Object> {
38+
39+
private final Class<?> targetType;
40+
private final MappingContext<? extends PersistentEntity<?, ?>, ? extends PersistentProperty<?>> context;
41+
private final EntityInstantiator instantiator;
42+
43+
/**
44+
* Creates a new {@link Converter} to instantiate DTOs.
45+
*
46+
* @param dtoType must not be {@literal null}.
47+
* @param context must not be {@literal null}.
48+
* @param entityInstantiators must not be {@literal null}.
49+
*/
50+
public DtoInstantiatingConverter(Class<?> dtoType,
51+
MappingContext<? extends PersistentEntity<?, ?>, ? extends PersistentProperty<?>> context,
52+
EntityInstantiators entityInstantiators) {
53+
54+
Assert.notNull(dtoType, "DTO type must not be null!");
55+
Assert.notNull(context, "MappingContext must not be null!");
56+
Assert.notNull(entityInstantiators, "EntityInstantiators must not be null!");
57+
58+
this.targetType = dtoType;
59+
this.context = context;
60+
this.instantiator = entityInstantiators.getInstantiatorFor(context.getRequiredPersistentEntity(dtoType));
61+
}
62+
63+
/*
64+
* (non-Javadoc)
65+
* @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
66+
*/
67+
@Override
68+
@SuppressWarnings({ "rawtypes", "unchecked" })
69+
public Object convert(Object source) {
70+
71+
if (targetType.isInterface()) {
72+
return source;
73+
}
74+
75+
PersistentEntity<?, ?> sourceEntity = context.getRequiredPersistentEntity(source.getClass());
76+
PersistentPropertyAccessor<?> sourceAccessor = sourceEntity.getPropertyAccessor(source);
77+
PersistentEntity<?, ?> targetEntity = context.getRequiredPersistentEntity(targetType);
78+
PreferredConstructor<?, ? extends PersistentProperty<?>> constructor = targetEntity.getPersistenceConstructor();
79+
80+
Object dto = instantiator.createInstance(targetEntity, new ParameterValueProvider() {
81+
82+
@Override
83+
public Object getParameterValue(Parameter parameter) {
84+
return sourceAccessor.getProperty(sourceEntity.getPersistentProperty(parameter.getName()));
85+
}
86+
});
87+
88+
PersistentPropertyAccessor<?> dtoAccessor = targetEntity.getPropertyAccessor(dto);
89+
90+
targetEntity.doWithProperties((SimplePropertyHandler) property -> {
91+
92+
if (constructor.isConstructorParameter(property)) {
93+
return;
94+
}
95+
96+
dtoAccessor.setProperty(property,
97+
sourceAccessor.getProperty(sourceEntity.getPersistentProperty(property.getName())));
98+
});
99+
100+
return dto;
101+
}
102+
}

src/main/java/org/springframework/data/keyvalue/repository/support/KeyValueRepositoryFactory.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.springframework.data.mapping.context.MappingContext;
3232
import org.springframework.data.projection.ProjectionFactory;
3333
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
34+
import org.springframework.data.querydsl.SimpleEntityPathResolver;
3435
import org.springframework.data.repository.core.EntityInformation;
3536
import org.springframework.data.repository.core.NamedQueries;
3637
import org.springframework.data.repository.core.RepositoryInformation;
@@ -152,12 +153,12 @@ protected RepositoryFragments getRepositoryFragments(RepositoryMetadata metadata
152153

153154
/**
154155
* Creates {@link RepositoryFragments} based on {@link RepositoryMetadata} to add Key-Value-specific extensions.
155-
* Typically adds a {@link QuerydslMongoPredicateExecutor} if the repository interface uses Querydsl.
156+
* Typically adds a {@link QuerydslKeyValuePredicateExecutor} if the repository interface uses Querydsl.
156157
* <p>
157158
* Can be overridden by subclasses to customize {@link RepositoryFragments}.
158159
*
159160
* @param metadata repository metadata.
160-
* @param operations the MongoDB operations manager.
161+
* @param operations the KeyValue operations manager.
161162
* @return
162163
* @since 2.6
163164
*/
@@ -171,7 +172,8 @@ protected RepositoryFragments getRepositoryFragments(RepositoryMetadata metadata
171172
}
172173

173174
return RepositoryFragments
174-
.just(new QuerydslKeyValuePredicateExecutor<>(getEntityInformation(metadata.getDomainType()), operations));
175+
.just(new QuerydslKeyValuePredicateExecutor<>(getEntityInformation(metadata.getDomainType()),
176+
getProjectionFactory(), operations, SimpleEntityPathResolver.INSTANCE));
175177
}
176178

177179
return RepositoryFragments.empty();

0 commit comments

Comments
 (0)