diff --git a/repository/src/main/java/org/springframework/data/rest/repository/JpaEntityMetadata.java b/repository/src/main/java/org/springframework/data/rest/repository/JpaEntityMetadata.java index 0fe82f32b..05e0f31da 100644 --- a/repository/src/main/java/org/springframework/data/rest/repository/JpaEntityMetadata.java +++ b/repository/src/main/java/org/springframework/data/rest/repository/JpaEntityMetadata.java @@ -127,18 +127,26 @@ public class JpaEntityMetadata { } public Object get(String name, Object target) { - try { - return fields.get(name).get(target); - } catch (IllegalAccessException e) { - throw new IllegalStateException(e); + if (fields.containsKey(name)) { + try { + return fields.get(name).get(target); + } catch (IllegalAccessException e) { + throw new IllegalStateException(e); + } + } else { + throw new NoSuchFieldError(name); } } public void set(String name, Object arg, Object target) { - try { - fields.get(name).set(target, arg); - } catch (IllegalAccessException e) { - throw new IllegalStateException(e); + if (fields.containsKey(name)) { + try { + fields.get(name).set(target, arg); + } catch (IllegalAccessException e) { + throw new IllegalStateException(e); + } + } else { + throw new NoSuchFieldError(name); } } diff --git a/repository/src/main/java/org/springframework/data/rest/repository/JpaRepositoryMetadata.java b/repository/src/main/java/org/springframework/data/rest/repository/JpaRepositoryMetadata.java index 4d797ffb5..07568bb22 100644 --- a/repository/src/main/java/org/springframework/data/rest/repository/JpaRepositoryMetadata.java +++ b/repository/src/main/java/org/springframework/data/rest/repository/JpaRepositoryMetadata.java @@ -1,5 +1,6 @@ package org.springframework.data.rest.repository; +import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; @@ -39,7 +40,8 @@ public class JpaRepositoryMetadata implements InitializingBean, ApplicationConte this.metamodel = entityManager.getMetamodel(); } - public CrudRepository repositoryFor(String name) { + @SuppressWarnings({"unchecked"}) + public CrudRepository repositoryFor(String name) { if (null != name) { for (Map.Entry, RepositoryCacheEntry> entry : repositories.entrySet()) { if (name.equals(repositoryNameFor(entry.getValue().repository))) { @@ -50,7 +52,8 @@ public class JpaRepositoryMetadata implements InitializingBean, ApplicationConte return null; } - public CrudRepository repositoryFor(Class domainClass) { + @SuppressWarnings({"unchecked"}) + public CrudRepository repositoryFor(Class domainClass) { RepositoryCacheEntry entry = repositories.get(domainClass); if (null != entry) { return entry.repository; @@ -58,7 +61,8 @@ public class JpaRepositoryMetadata implements InitializingBean, ApplicationConte return null; } - public EntityInformation entityInfoFor(Class domainClass) { + @SuppressWarnings({"unchecked"}) + public EntityInformation entityInfoFor(Class domainClass) { RepositoryCacheEntry entry = repositories.get(domainClass); if (null != entry) { return entry.entityInfo; @@ -70,7 +74,8 @@ public class JpaRepositoryMetadata implements InitializingBean, ApplicationConte return metamodel.entity(domainClass); } - public EntityInformation entityInfoFor(CrudRepository repository) { + @SuppressWarnings({"unchecked"}) + public EntityInformation entityInfoFor(CrudRepository repository) { for (Map.Entry, RepositoryCacheEntry> entry : repositories.entrySet()) { if (entry.getValue().repository == repository) { return entry.getValue().entityInfo; @@ -116,7 +121,7 @@ public class JpaRepositoryMetadata implements InitializingBean, ApplicationConte return names; } - public void setRepositories(Collection repositories) { + public void setRepositories(Collection repositories) { for (CrudRepository repository : repositories) { Class repoClass = AopUtils.getTargetClass(repository); Field infoField = ReflectionUtils.findField(repoClass, "entityInformation"); diff --git a/repository/src/test/groovy/org/springframework/data/rest/repository/spec/JpaMetadataSpec.groovy b/repository/src/test/groovy/org/springframework/data/rest/repository/spec/JpaMetadataSpec.groovy index 7a09905ab..c2e4d4d86 100644 --- a/repository/src/test/groovy/org/springframework/data/rest/repository/spec/JpaMetadataSpec.groovy +++ b/repository/src/test/groovy/org/springframework/data/rest/repository/spec/JpaMetadataSpec.groovy @@ -1,14 +1,15 @@ package org.springframework.data.rest.repository.spec -import javax.persistence.Entity import javax.persistence.EntityManager -import javax.persistence.GeneratedValue -import javax.persistence.Id import javax.persistence.PersistenceContext import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.ApplicationContext import org.springframework.data.repository.CrudRepository import org.springframework.data.rest.repository.JpaRepositoryMetadata +import org.springframework.data.rest.repository.test.Family +import org.springframework.data.rest.repository.test.FamilyRepository +import org.springframework.data.rest.repository.test.Person +import org.springframework.data.rest.repository.test.PersonRepository import org.springframework.test.context.ContextConfiguration import spock.lang.Specification @@ -24,41 +25,50 @@ class JpaMetadataSpec extends Specification { EntityManager entityManager @Autowired Collection repositories + @Autowired JpaRepositoryMetadata repoMeta - def setup() { - repoMeta = new JpaRepositoryMetadata( - repositories: repositories, - applicationContext: applicationContext, - entityManager: entityManager - ) - repoMeta.afterPropertiesSet() - } - def "finds repositories in ApplicationContext"() { - when: - def repo = repoMeta.repositoryFor("simple") + when: "find repo by String identifier" + def repo = repoMeta.repositoryFor("person") then: null != repo - repo instanceof SimpleRepository + repo instanceof PersonRepository - when: - repo = repoMeta.repositoryFor(Simple) + when: "find repo by domain Class" + repo = repoMeta.repositoryFor(Family) then: null != repo - repo instanceof SimpleRepository + repo instanceof FamilyRepository + + } + + def "provides entity metadata"() { + + given: + def personRepo = repoMeta.repositoryFor(Person) + def familyRepo = repoMeta.repositoryFor(Family) + def johnDoe = personRepo.save(new Person("John Doe")) + def janeDoe = personRepo.save(new Person("Jane Doe")) + def doeFamily = familyRepo.save(new Family( + surname: "Doe", + members: [johnDoe, janeDoe] + )) + + when: + def personMeta = repoMeta.entityMetadataFor(Person) + def familyMeta = repoMeta.entityMetadataFor(Family) + + then: + personMeta.get("name", johnDoe) == "John Doe" + familyMeta.get("surname", doeFamily) == "Doe" + familyMeta.get("members", doeFamily).size() == 2 + personMeta.embeddedAttributes().size() == 1 + familyMeta.linkedAttributes().size() == 1 } } - -@Entity -class Simple { - @Id @GeneratedValue Long id - String name -} - -interface SimpleRepository extends CrudRepository {} diff --git a/repository/src/test/java/org/springframework/data/rest/repository/test/Family.java b/repository/src/test/java/org/springframework/data/rest/repository/test/Family.java new file mode 100644 index 000000000..d160d1c8e --- /dev/null +++ b/repository/src/test/java/org/springframework/data/rest/repository/test/Family.java @@ -0,0 +1,57 @@ +package org.springframework.data.rest.repository.test; + +import java.util.List; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.OneToMany; + +/** + * @author Jon Brisbin + */ +@Entity +public class Family { + + @Id + @GeneratedValue + private Long id; + private String surname; + @OneToMany + private List members; + + public Family() { + } + + public Family(String surname) { + this.surname = surname; + } + + public Long getId() { + return id; + } + + public String getSurname() { + return surname; + } + + public void setSurname(String surname) { + this.surname = surname; + } + + public List getMembers() { + return members; + } + + public void setMembers(List members) { + this.members = members; + } + + @Override public String toString() { + return "Family{" + + "id=" + id + + ", surname='" + surname + '\'' + + ", members=" + members + + '}'; + } + +} diff --git a/repository/src/test/java/org/springframework/data/rest/repository/test/FamilyRepository.java b/repository/src/test/java/org/springframework/data/rest/repository/test/FamilyRepository.java new file mode 100644 index 000000000..e25b5bddd --- /dev/null +++ b/repository/src/test/java/org/springframework/data/rest/repository/test/FamilyRepository.java @@ -0,0 +1,9 @@ +package org.springframework.data.rest.repository.test; + +import org.springframework.data.repository.CrudRepository; + +/** + * @author Jon Brisbin + */ +public interface FamilyRepository extends CrudRepository { +} diff --git a/repository/src/test/java/org/springframework/data/rest/repository/test/Person.java b/repository/src/test/java/org/springframework/data/rest/repository/test/Person.java new file mode 100644 index 000000000..e0928543e --- /dev/null +++ b/repository/src/test/java/org/springframework/data/rest/repository/test/Person.java @@ -0,0 +1,44 @@ +package org.springframework.data.rest.repository.test; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +/** + * @author Jon Brisbin + */ +@Entity +public class Person { + + @Id + @GeneratedValue + private Long id; + private String name; + + public Person() { + } + + public Person(String name) { + this.name = name; + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override public String toString() { + return "Person{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } + +} diff --git a/repository/src/test/java/org/springframework/data/rest/repository/test/PersonRepository.java b/repository/src/test/java/org/springframework/data/rest/repository/test/PersonRepository.java new file mode 100644 index 000000000..7678d816e --- /dev/null +++ b/repository/src/test/java/org/springframework/data/rest/repository/test/PersonRepository.java @@ -0,0 +1,9 @@ +package org.springframework.data.rest.repository.test; + +import org.springframework.data.repository.CrudRepository; + +/** + * @author Jon Brisbin + */ +public interface PersonRepository extends CrudRepository { +} diff --git a/repository/src/test/resources/JpaMetadataSpec-persistence.xml b/repository/src/test/resources/JpaMetadataSpec-persistence.xml index abaac1ce0..56846a7f4 100644 --- a/repository/src/test/resources/JpaMetadataSpec-persistence.xml +++ b/repository/src/test/resources/JpaMetadataSpec-persistence.xml @@ -1,7 +1,8 @@ - org.springframework.data.rest.repository.spec.Simple + org.springframework.data.rest.repository.test.Person + org.springframework.data.rest.repository.test.Family diff --git a/repository/src/test/resources/JpaMetadataSpec-test.xml b/repository/src/test/resources/JpaMetadataSpec-test.xml index 988ff37af..ecc285c52 100644 --- a/repository/src/test/resources/JpaMetadataSpec-test.xml +++ b/repository/src/test/resources/JpaMetadataSpec-test.xml @@ -7,6 +7,8 @@ http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd"> + + @@ -18,9 +20,14 @@ + + + - + - + + +