Skip to content

Commit

Permalink
Support multiple levels of repository interfaces in Spring Data JPA
Browse files Browse the repository at this point in the history
Closes: #31570
  • Loading branch information
geoand committed Mar 3, 2023
1 parent 3bf5153 commit 646d13d
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;

import jakarta.transaction.Transactional;
Expand Down Expand Up @@ -56,18 +58,15 @@ public DerivedMethodsAdder(IndexView index, TypeBundle typeBundle, ClassOutput n
public void add(ClassCreator classCreator, FieldDescriptor entityClassFieldDescriptor,
String generatedClassName, ClassInfo repositoryClassInfo, ClassInfo entityClassInfo) {
MethodNameParser methodNameParser = new MethodNameParser(entityClassInfo, index);
List<MethodInfo> repoMethods = new ArrayList<>(repositoryClassInfo.methods());
LinkedHashSet<MethodInfo> repoMethods = new LinkedHashSet<>(repositoryClassInfo.methods());

// Remember custom return type methods: {resultType:[methodName]}
Map<DotName, List<String>> customResultTypes = new HashMap<>(3);
Map<DotName, DotName> customResultTypeImplNames = new HashMap<>(3);

//As intermediate interfaces are supported for spring data repositories, we need to search the methods declared in such interfaced and add them to the methods to implement list
for (DotName extendedInterface : repositoryClassInfo.interfaceNames()) {
if (GenerationUtil.isIntermediateRepository(extendedInterface, index)) {
List<MethodInfo> methods = index.getClassByName(extendedInterface).methods();
repoMethods.addAll(methods);
}
addAllMethodOfIntermediateRepository(extendedInterface, repoMethods);
}
for (MethodInfo method : repoMethods) {
if (method.annotation(DotNames.SPRING_DATA_QUERY) != null) { // handled by CustomQueryMethodsAdder
Expand Down Expand Up @@ -288,6 +287,17 @@ public void add(ClassCreator classCreator, FieldDescriptor entityClassFieldDescr
}
}

private void addAllMethodOfIntermediateRepository(DotName interfaceDotName, Set<MethodInfo> result) {
if (GenerationUtil.isIntermediateRepository(interfaceDotName, index)) {
ClassInfo classInfo = index.getClassByName(interfaceDotName);
List<MethodInfo> methods = classInfo.methods();
result.addAll(methods);
for (DotName superInterface : classInfo.interfaceNames()) {
addAllMethodOfIntermediateRepository(superInterface, result);
}
}
}

private void generateCustomResultTypes(DotName interfaceName, DotName implName, ClassInfo entityClassInfo,
List<String> queryMethods) {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package io.quarkus.it.spring.data.jpa;

public interface ByPassHolder {

boolean isBypass();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import org.springframework.data.repository.NoRepositoryBean;

@NoRepositoryBean
public interface IntermediateRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
public interface BypassHolderRepository<T extends ByPassHolder, ID extends Serializable> extends JpaRepository<T, ID> {

default public void doNothing() {
}
Expand All @@ -15,4 +15,5 @@ default public T findMandatoryById(ID id) {
return findById(id).orElseThrow(() -> new IllegalStateException("not found: " + id));
}

Post findFirstByBypassTrue();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.quarkus.it.spring.data.jpa;

import java.time.ZonedDateTime;
import java.util.List;

/**
* Used to ensure that entity relationships work correctly
*/
public interface IntermediatePostRepository extends BypassHolderRepository<Post, Long> {

List<Post> findByPostedBefore(ZonedDateTime zdt);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

@Entity(name = "Post")
@Table(name = "post")
public class Post {
public class Post implements ByPassHolder {

@Id
@SequenceGenerator(name = "postSeqGen", sequenceName = "postSeq", initialValue = 100, allocationSize = 1)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
package io.quarkus.it.spring.data.jpa;

import java.time.ZonedDateTime;
import java.util.List;

/**
* Used to ensure that entity relationships work correctly
*/
public interface PostRepository extends IntermediateRepository<Post, Long> {

Post findFirstByBypassTrue();

List<Post> findByPostedBefore(ZonedDateTime zdt);
public interface PostRepository extends IntermediatePostRepository {

List<Post> findAllByOrganization(String organization);

Expand Down

0 comments on commit 646d13d

Please sign in to comment.