Skip to content

Commit 035f8ca

Browse files
committed
Fix #23 Stop using illegal reflective access
1 parent de94ecf commit 035f8ca

File tree

5 files changed

+93
-46
lines changed

5 files changed

+93
-46
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.cosium.spring.data.jpa.entity.graph.repository.query;
2+
3+
import com.cosium.spring.data.jpa.entity.graph.domain.EntityGraph;
4+
import java.lang.reflect.Method;
5+
import org.springframework.core.MethodParameter;
6+
import org.springframework.data.jpa.repository.query.JpaParameters;
7+
8+
/** @author Réda Housni Alaoui */
9+
class EntityGraphAwareJpaParameters extends JpaParameters {
10+
11+
public EntityGraphAwareJpaParameters(Method method) {
12+
super(method);
13+
}
14+
15+
@Override
16+
protected JpaParameter createParameter(MethodParameter parameter) {
17+
return new EntityGraphAwareJpaParameter(parameter);
18+
}
19+
20+
private static class EntityGraphAwareJpaParameter extends JpaParameters.JpaParameter {
21+
22+
private final MethodParameter parameter;
23+
24+
protected EntityGraphAwareJpaParameter(MethodParameter parameter) {
25+
super(parameter);
26+
this.parameter = parameter;
27+
}
28+
29+
@Override
30+
public boolean isBindable() {
31+
return !EntityGraph.class.equals(parameter.getParameterType()) && super.isBindable();
32+
}
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.cosium.spring.data.jpa.entity.graph.repository.query;
2+
3+
import java.lang.reflect.Method;
4+
import org.springframework.data.jpa.provider.QueryExtractor;
5+
import org.springframework.data.jpa.repository.query.JpaParameters;
6+
import org.springframework.data.jpa.repository.query.JpaQueryMethod;
7+
import org.springframework.data.projection.ProjectionFactory;
8+
import org.springframework.data.repository.core.RepositoryMetadata;
9+
10+
/** @author Réda Housni Alaoui */
11+
class EntityGraphAwareJpaQueryMethod extends JpaQueryMethod {
12+
13+
protected EntityGraphAwareJpaQueryMethod(
14+
Method method,
15+
RepositoryMetadata metadata,
16+
ProjectionFactory factory,
17+
QueryExtractor extractor) {
18+
super(method, metadata, factory, extractor);
19+
}
20+
21+
@Override
22+
protected JpaParameters createParameters(Method method) {
23+
return new EntityGraphAwareJpaParameters(method);
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.cosium.spring.data.jpa.entity.graph.repository.query;
2+
3+
import java.lang.reflect.Method;
4+
import org.springframework.data.jpa.provider.QueryExtractor;
5+
import org.springframework.data.jpa.repository.query.JpaQueryMethod;
6+
import org.springframework.data.jpa.repository.query.JpaQueryMethodFactory;
7+
import org.springframework.data.projection.ProjectionFactory;
8+
import org.springframework.data.repository.core.RepositoryMetadata;
9+
10+
/** @author Réda Housni Alaoui */
11+
public class EntityGraphAwareJpaQueryMethodFactory implements JpaQueryMethodFactory {
12+
13+
private final QueryExtractor extractor;
14+
15+
public EntityGraphAwareJpaQueryMethodFactory(QueryExtractor extractor) {
16+
this.extractor = extractor;
17+
}
18+
19+
@Override
20+
public JpaQueryMethod build(
21+
Method method, RepositoryMetadata metadata, ProjectionFactory factory) {
22+
return new EntityGraphAwareJpaQueryMethod(method, metadata, factory, extractor);
23+
}
24+
}

src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphJpaRepositoryFactory.java

Lines changed: 8 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
11
package com.cosium.spring.data.jpa.entity.graph.repository.support;
22

3+
import static org.springframework.data.querydsl.QuerydslUtils.QUERY_DSL_PRESENT;
4+
35
import com.cosium.spring.data.jpa.entity.graph.domain.EntityGraph;
6+
import com.cosium.spring.data.jpa.entity.graph.repository.query.EntityGraphAwareJpaQueryMethodFactory;
7+
import javax.persistence.EntityManager;
8+
import org.springframework.data.jpa.provider.PersistenceProvider;
49
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
510
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
611
import org.springframework.data.repository.core.RepositoryMetadata;
7-
import org.springframework.data.repository.query.Parameter;
8-
import org.springframework.data.repository.query.Parameters;
9-
import org.springframework.util.ReflectionUtils;
10-
11-
import javax.persistence.EntityManager;
12-
import java.lang.reflect.Field;
13-
import java.lang.reflect.Modifier;
14-
import java.util.ArrayList;
15-
import java.util.List;
16-
17-
import static org.springframework.data.querydsl.QuerydslUtils.QUERY_DSL_PRESENT;
1812

1913
/**
2014
* This repository factory allows to build {@link EntityGraph} aware repositories. Created on
@@ -24,10 +18,6 @@
2418
*/
2519
public class EntityGraphJpaRepositoryFactory extends JpaRepositoryFactory {
2620

27-
static {
28-
addEntityGraphToSpecialTypes();
29-
}
30-
3121
/**
3222
* Creates a new {@link JpaRepositoryFactory}.
3323
*
@@ -36,34 +26,9 @@ public class EntityGraphJpaRepositoryFactory extends JpaRepositoryFactory {
3626
public EntityGraphJpaRepositoryFactory(EntityManager entityManager) {
3727
super(entityManager);
3828
addRepositoryProxyPostProcessor(new RepositoryMethodEntityGraphExtractor(entityManager));
39-
}
40-
41-
/**
42-
* Add {@link EntityGraph} to the special types.<br>
43-
* {@link EntityGraph} must be considered as a special type by Spring Data JPA.<br>
44-
* For this to occur, {@link EntityGraph} must be part of Spring Data JPA arrays storing special
45-
* types.<br>
46-
* Once a type is marked as special, Spring Data JPA will not try to bind it to an under
47-
* construction query.
48-
*/
49-
private static void addEntityGraphToSpecialTypes() {
50-
addEntityGraphToSpecialTypes(Parameters.class, "TYPES");
51-
addEntityGraphToSpecialTypes(Parameter.class, "TYPES");
52-
}
53-
54-
private static void addEntityGraphToSpecialTypes(Class<?> clazz, String fieldName) {
55-
try {
56-
Field field = ReflectionUtils.findField(clazz, fieldName);
57-
field.setAccessible(true);
58-
Field modifiersField = Field.class.getDeclaredField("modifiers");
59-
modifiersField.setAccessible(true);
60-
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
61-
List<Class<?>> specialTypes = new ArrayList<Class<?>>((List<Class<?>>) field.get(null));
62-
specialTypes.add(EntityGraph.class);
63-
ReflectionUtils.setField(field, null, specialTypes);
64-
} catch (Exception e) {
65-
throw new RuntimeException(e.getMessage(), e);
66-
}
29+
setQueryMethodFactory(
30+
new EntityGraphAwareJpaQueryMethodFactory(
31+
PersistenceProvider.fromEntityManager(entityManager)));
6732
}
6833

6934
@Override

src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphJpaRepositoryFactoryBean.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
package com.cosium.spring.data.jpa.entity.graph.repository.support;
22

3+
import java.io.Serializable;
4+
import javax.persistence.EntityManager;
35
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
46
import org.springframework.data.repository.Repository;
57
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
68

7-
import javax.persistence.EntityManager;
8-
import java.io.Serializable;
9-
109
/**
1110
* Forces the use of {@link RepositoryEntityManagerEntityGraphInjector} while targeting {@link
1211
* EntityGraphJpaRepositoryFactory}.

0 commit comments

Comments
 (0)