Composite key for jps repo with @IdClass

This commit is contained in:
aboyko
2023-12-14 16:35:24 -05:00
parent 1539bebde3
commit de4a1322cf
3 changed files with 61 additions and 7 deletions

View File

@@ -30,7 +30,11 @@ public class Annotations {
public static final String NO_REPO_BEAN = "org.springframework.data.repository.NoRepositoryBean";
public static final String SPRING_ENTITY_ID = "org.springframework.data.annotation.Id";
public static final String JPA_JAKARTA_ENTITY_ID = "jakarta.persistence.Id";
public static final String JPA_JAVAX_ENTITY_ID = "javax.persistence.Id";
public static final String JPA_JAVAX_ENTITY_ID = "javax.persistence.Id";
public static final String JPA_JAKARTA_EMBEDDED_ID = "jakarta.persistence.EmbeddedId";
public static final String JPA_JAVAX_EMBEDDED_ID = "javax.persistence.EmbeddedId";
public static final String JPA_JAKARTA_ID_CLASS = "jakarta.persistence.IdClass";
public static final String JPA_JAVAX_ID_CLASS = "javax.persistence.IdClass";
public static final String AUTOWIRED = "org.springframework.beans.factory.annotation.Autowired";
public static final String INJECT = "javax.inject.Inject";

View File

@@ -18,6 +18,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@@ -331,7 +332,17 @@ public class EntityIdForRepoReconciler implements JdtAstReconciler {
private static List<ITypeBinding> findAnnotatedIdTypes(ITypeBinding type, Set<String> visited) {
List<ITypeBinding> idTypes = new ArrayList<>();
List<String> idAnnotations = List.of(Annotations.SPRING_ENTITY_ID, Annotations.JPA_JAKARTA_ENTITY_ID, Annotations.JPA_JAVAX_ENTITY_ID);
for (IAnnotationBinding a : type.getAnnotations()) {
switch (a.getAnnotationType().getQualifiedName()) {
case Annotations.JPA_JAKARTA_ID_CLASS:
case Annotations.JPA_JAVAX_ID_CLASS:
Optional<Object> opt = Arrays.stream(a.getAllMemberValuePairs()).filter(p -> "value".equals(p.getName())).map(p -> p.getValue()).findFirst();
if (opt.isPresent() && opt.get() instanceof ITypeBinding) {
return List.of((ITypeBinding) opt.get());
}
}
}
List<String> idAnnotations = List.of(Annotations.SPRING_ENTITY_ID, Annotations.JPA_JAKARTA_ENTITY_ID, Annotations.JPA_JAVAX_ENTITY_ID, Annotations.JPA_JAKARTA_EMBEDDED_ID, Annotations.JPA_JAVAX_EMBEDDED_ID);
for (IVariableBinding m : type.getDeclaredFields()) {
String s = fieldSignature(m);
if (!visited.contains(s) && isAnnotationCompatible(m.getAnnotations(), idAnnotations)) {

View File

@@ -1047,16 +1047,15 @@ public class EntityIdForRepoReconcilerTest extends BaseReconcilerTest {
}
@Test
void compositeId() throws Exception {
void compositeId_1() throws Exception {
Path customerSource = createFile("Customer.java", """
package demo;
import org.springframework.data.annotation.Id;
import jakarta.persistence.IdClass;
@IdClass(CustomerId.class)
public class Customer {
@Id String id;
@Id String id_additional;
}
""");
@@ -1078,5 +1077,45 @@ public class EntityIdForRepoReconcilerTest extends BaseReconcilerTest {
assertEquals(0, problems.size());
}
@Test
void compositeId_2() throws Exception {
Path customerSource = createFile("Customer.java", """
package demo;
import jakarta.persistence.IdClass;
import org.springframework.data.annotation.Id;
@IdClass(CustomerId.class)
public class Customer {
@Id Long id
}
""");
Path customerId = createFile("CustomerId.java", """
package demo;
public record CustomerId(String id) {}
""");
String source = """
package demo;
import org.springframework.data.repository.Repository;
interface CustomerRepository extends Repository<Customer, Long> {}
""";
List<ReconcileProblem> problems = reconcile("CustomerRepository.java", source, false, customerSource, customerId);
assertEquals(1, problems.size());
ReconcileProblem problem = problems.get(0);
assertEquals(Boot2JavaProblemType.DOMAIN_ID_FOR_REPOSITORY, problem.getType());
String markedStr = source.substring(problem.getOffset(), problem.getOffset() + problem.getLength());
assertEquals("Long", markedStr);
assertEquals("Expected Domain ID type is 'demo.CustomerId'", problem.getMessage());
}
}