diff --git a/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformation.java b/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformation.java index b221f8875..1a2e3aa9c 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformation.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformation.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2013 the original author or authors. + * Copyright 2011-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ import javax.persistence.metamodel.SingularAttribute; import org.springframework.data.repository.core.EntityInformation; /** - * Extension of {@link EntityInformation} to capture aditional JPA specific information about entities. + * Extension of {@link EntityInformation} to capture additional JPA specific information about entities. * * @author Oliver Gierke * @author Thomas Darimont @@ -38,7 +38,7 @@ public interface JpaEntityInformation extends Entity SingularAttribute getIdAttribute(); /** - * Returns {@literal true} if the entity has a composite id + * Returns {@literal true} if the entity has a composite id. * * @return */ diff --git a/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java b/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java index 5851f0ff5..999487b22 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java @@ -233,27 +233,39 @@ public class SimpleJpaRepository implements JpaRepos Assert.notNull(id, "The given id must not be null!"); - if (entityInformation.getIdAttribute() != null) { - - String placeholder = provider.getCountQueryPlaceholder(); - String entityName = entityInformation.getEntityName(); - Iterable idAttributeNames = entityInformation.getIdAttributeNames(); - String existsQuery = QueryUtils.getExistsQueryString(entityName, placeholder, idAttributeNames); - - TypedQuery query = em.createQuery(existsQuery, Long.class); - - if (entityInformation.hasCompositeId()) { - for (String idAttributeName : idAttributeNames) { - query.setParameter(idAttributeName, entityInformation.getCompositeIdAttributeValue(id, idAttributeName)); - } - } else { - query.setParameter(idAttributeNames.iterator().next(), id); - } - - return query.getSingleResult() == 1L; - } else { + if (entityInformation.getIdAttribute() == null) { return findOne(id) != null; } + + String placeholder = provider.getCountQueryPlaceholder(); + String entityName = entityInformation.getEntityName(); + Iterable idAttributeNames = entityInformation.getIdAttributeNames(); + String existsQuery = QueryUtils.getExistsQueryString(entityName, placeholder, idAttributeNames); + + TypedQuery query = em.createQuery(existsQuery, Long.class); + + if (!entityInformation.hasCompositeId()) { + query.setParameter(idAttributeNames.iterator().next(), id); + return query.getSingleResult() == 1L; + } + + for (String idAttributeName : idAttributeNames) { + + Object idAttributeValue = entityInformation.getCompositeIdAttributeValue(id, idAttributeName); + + boolean complexIdParameterValueDiscovered = idAttributeValue != null + && !query.getParameter(idAttributeName).getParameterType().isAssignableFrom(idAttributeValue.getClass()); + + if (complexIdParameterValueDiscovered) { + + // fall-back to findOne(id) which does the proper mapping for the parameter. + return findOne(id) != null; + } + + query.setParameter(idAttributeName, idAttributeValue); + } + + return query.getSingleResult() == 1L; } /* diff --git a/src/test/java/org/springframework/data/jpa/repository/RepositoryWithCompositeKeyTests.java b/src/test/java/org/springframework/data/jpa/repository/RepositoryWithCompositeKeyTests.java index 6fd98addf..2871859cf 100644 --- a/src/test/java/org/springframework/data/jpa/repository/RepositoryWithCompositeKeyTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/RepositoryWithCompositeKeyTests.java @@ -215,4 +215,52 @@ public class RepositoryWithCompositeKeyTests { assertThat(result.get(0), is(emp3)); assertThat(result.get(1), is(emp1)); } + + /** + * @see DATAJPA-527 + */ + @Test + public void testExistsWithIdClass() { + + IdClassExampleDepartment dep = new IdClassExampleDepartment(); + dep.setName("TestDepartment"); + dep.setDepartmentId(-1); + + IdClassExampleEmployee emp = new IdClassExampleEmployee(); + emp.setDepartment(dep); + + employeeRepositoryWithIdClass.save(emp); + + IdClassExampleEmployeePK key = new IdClassExampleEmployeePK(); + key.setDepartment(dep.getDepartmentId()); + key.setEmpId(emp.getEmpId()); + + assertThat(employeeRepositoryWithIdClass.exists(key), is(true)); + } + + /** + * @see DATAJPA-527 + */ + @Test + public void testExistsWithEmbeddedId() { + + EmbeddedIdExampleDepartment dep1 = new EmbeddedIdExampleDepartment(); + dep1.setDepartmentId(1L); + dep1.setName("Dep1"); + + EmbeddedIdExampleEmployeePK key = new EmbeddedIdExampleEmployeePK(); + key.setDepartmentId(1L); + key.setEmployeeId(1L); + + EmbeddedIdExampleEmployee emp = new EmbeddedIdExampleEmployee(); + emp.setDepartment(dep1); + emp.setEmployeePk(key); + + emp = employeeRepositoryWithEmbeddedId.save(emp); + + key.setDepartmentId(emp.getDepartment().getDepartmentId()); + key.setEmployeeId(emp.getEmployeePk().getEmployeeId()); + + assertThat(employeeRepositoryWithEmbeddedId.exists(key), is(true)); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryTests.java b/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryTests.java index c5eafef1e..b827d9ea9 100644 --- a/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2013 the original author or authors. + * Copyright 2008-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,14 +40,14 @@ import org.springframework.transaction.annotation.Transactional; * Integration test for {@link JpaRepository}. * * @author Oliver Gierke + * @author Thomas Darimont */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({ "classpath:infrastructure.xml" }) @Transactional public class JpaRepositoryTests { - @PersistenceContext - EntityManager em; + @PersistenceContext EntityManager em; JpaRepository repository; CrudRepository idClassRepository; @@ -104,6 +104,23 @@ public class JpaRepositoryTests { assertThat(idClassRepository.exists(new SampleWithIdClassPK(1L, 2L)), is(false)); } + /** + * @see DATAJPA-527 + */ + @Test + public void executesExistsForEntityWithIdClass() { + + SampleWithIdClass entity = new SampleWithIdClass(1L, 1L); + idClassRepository.save(entity); + + assertThat(entity.getFirst(), is(notNullValue())); + assertThat(entity.getSecond(), is(notNullValue())); + + SampleWithIdClassPK id = new SampleWithIdClassPK(entity.getFirst(), entity.getSecond()); + + assertThat(idClassRepository.exists(id), is(true)); + } + private static interface SampleEntityRepository extends JpaRepository { }