Skip to content

Instantly share code, notes, and snippets.

@elucash
Created October 9, 2016 22:09
Show Gist options
  • Save elucash/a701a64ce608de6c6780052ab3b1eb00 to your computer and use it in GitHub Desktop.
Save elucash/a701a64ce608de6c6780052ab3b1eb00 to your computer and use it in GitHub Desktop.
Resolves public constructors in spring data. But hard to plug this into configuration
package springhack;
import java.lang.annotation.Annotation;
import java.util.List;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PreferredConstructor.Parameter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PreferredConstructor;
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.util.TypeInformation;
public class OverrideMongoMappingContext extends MongoMappingContext {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
super.setApplicationContext(applicationContext);
}
@Override
protected <T> BasicMongoPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
OverrideBasicMongoPersistentEntity<T> entity = new OverrideBasicMongoPersistentEntity<>(typeInformation);
if (applicationContext != null) {
entity.setApplicationContext(applicationContext);
}
return entity;
}
public static class OverrideBasicMongoPersistentEntity<T> extends BasicMongoPersistentEntity<T> {
private final ParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
private final TypeInformation<T> type;
private final PreferredConstructor<T, MongoPersistentProperty> constructor;
public OverrideBasicMongoPersistentEntity(TypeInformation<T> type) {
super(type);
this.type = type;
// new PreferredConstructorDiscoverer<>(null)
this.constructor = discoverConstructor();
}
private PreferredConstructor<T, MongoPersistentProperty> discoverConstructor() {
Class<?> rawOwningType = type.getType();
for (Constructor<?> candidate : rawOwningType.getDeclaredConstructors()) {
if (Modifier.isPublic(candidate.getModifiers())) {
return buildPreferredConstructor(candidate, type, this);
}
}
return null;
}
@SuppressWarnings({"unchecked", "rawtypes"})
private PreferredConstructor<T, MongoPersistentProperty> buildPreferredConstructor(
Constructor<?> constructor,
TypeInformation<T> typeInformation,
PersistentEntity<T, MongoPersistentProperty> entity) {
List<TypeInformation<?>> parameterTypes = typeInformation.getParameterTypes(constructor);
if (parameterTypes.isEmpty()) {
return new PreferredConstructor<>((Constructor<T>) constructor);
}
String[] parameterNames = discoverer.getParameterNames(constructor);
Parameter<Object, MongoPersistentProperty>[] parameters = new Parameter[parameterTypes.size()];
Annotation[][] parameterAnnotations = constructor.getParameterAnnotations();
for (int i = 0; i < parameterTypes.size(); i++) {
String name = parameterNames == null ? null : parameterNames[i];
TypeInformation<?> type = parameterTypes.get(i);
Annotation[] annotations = parameterAnnotations[i];
parameters[i] = new Parameter(name, type, annotations, entity);
}
return new PreferredConstructor<>((Constructor<T>) constructor, parameters);
}
@Override
public boolean isConstructorArgument(PersistentProperty<?> property) {
return constructor == null ? false : constructor.isConstructorParameter(property);
}
@Override
public PreferredConstructor<T, MongoPersistentProperty> getPersistenceConstructor() {
return constructor;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment