DATAJPA-696 - Polishing.

Moved logic to create an ad-hoc entity graph into Jpa21Utils to avoid having to create a PersistenceProvider instance just for the sake of creating such a graph. Moved test code for that into newly introduced Jpa21UtilsUnitTests.

JpaEntityGraph now uses an unmodifiable List instead of an array to prevent having to deal with modifications. Jpa21Utils now uses Collection sorting and reversing to be able to use the for-each loop.

Polished imports, JavaDoc and @since tags where necessary.

Original pull request: #140.
This commit is contained in:
Oliver Gierke
2015-05-12 17:10:53 +02:00
parent 1443b155db
commit 70ad616c4c
11 changed files with 165 additions and 163 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014 the original author or authors.
* Copyright 2014-2015 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.
@@ -15,37 +15,21 @@
*/
package org.springframework.data.jpa.provider;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.springframework.data.jpa.provider.PersistenceProvider.ECLIPSELINK;
import static org.springframework.data.jpa.provider.PersistenceProvider.GENERIC_JPA;
import static org.springframework.data.jpa.provider.PersistenceProvider.HIBERNATE;
import static org.springframework.data.jpa.provider.PersistenceProvider.OPEN_JPA;
import static org.springframework.data.jpa.provider.PersistenceProvider.fromEntityManager;
import static org.springframework.data.jpa.provider.PersistenceProvider.Constants.ECLIPSELINK_ENTITY_MANAGER_INTERFACE;
import static org.springframework.data.jpa.provider.PersistenceProvider.Constants.HIBERNATE43_ENTITY_MANAGER_INTERFACE;
import static org.springframework.data.jpa.provider.PersistenceProvider.Constants.HIBERNATE_ENTITY_MANAGER_INTERFACE;
import static org.springframework.data.jpa.provider.PersistenceProvider.Constants.OPENJPA_ENTITY_MANAGER_INTERFACE;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.springframework.data.jpa.provider.PersistenceProvider.*;
import static org.springframework.data.jpa.provider.PersistenceProvider.Constants.*;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityGraph;
import javax.persistence.EntityManager;
import javax.persistence.Subgraph;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.asm.ClassWriter;
import org.springframework.asm.Opcodes;
import org.springframework.data.jpa.repository.EntityGraph.EntityGraphType;
import org.springframework.data.jpa.repository.query.JpaEntityGraph;
import org.springframework.instrument.classloading.ShadowingClassLoader;
import org.springframework.util.ClassUtils;
@@ -118,26 +102,6 @@ public class PersistenceProviderUnitTests {
assertThat(fromEntityManager(em), is(GENERIC_JPA));
}
/**
* @see DATAJPA-696
*/
@Test
public void shouldBuildCorrectSubgraphForJpaEntityGraph() throws Exception {
EntityGraph<?> entityGraph = mock(EntityGraph.class);
Subgraph<?> subgraph = mock(Subgraph.class);
doReturn(subgraph).when(entityGraph).addSubgraph(anyString());
JpaEntityGraph jpaEntityGraph = new JpaEntityGraph("foo", EntityGraphType.FETCH,
new String[] { "foo", "gugu.gaga" });
PersistenceProvider.GENERIC_JPA.configureFetchGraphFrom(jpaEntityGraph, entityGraph);
verify(entityGraph, times(1)).addAttributeNodes("foo");
verify(entityGraph, times(1)).addSubgraph("gugu");
verify(subgraph, times(1)).addAttributeNodes("gaga");
}
private EntityManager mockProviderSpecificEntityManagerInterface(String interfaceName) throws ClassNotFoundException {
Class<?> providerSpecificEntityManagerInterface = InterfaceGenerator.generate(interfaceName, shadowingClassLoader,

View File

@@ -31,13 +31,16 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.sample.Role;
import org.springframework.data.jpa.domain.sample.User;
import org.springframework.data.jpa.repository.sample.RepositoryMethodsWithEntityGraphConfigJpaRepository;
import org.springframework.data.jpa.repository.sample.RepositoryMethodsWithEntityGraphConfigRepository;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
/**
* Integration tests for RepositoryMethodsWithEntityGraphConfigJpaRepository.
*
* @author Thomas Darimont
* @author Oliver Gierke
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:config/namespace-autoconfig-context.xml")
@@ -45,25 +48,25 @@ import org.springframework.transaction.annotation.Transactional;
public class EntityGraphRepositoryMethodsIntegrationTests {
@Autowired EntityManager em;
@Autowired RepositoryMethodsWithEntityGraphConfigJpaRepository repository;
@Autowired RepositoryMethodsWithEntityGraphConfigRepository repository;
User tom;
User olli;
User ollie;
Role role;
@Before
public void setup() {
tom = new User("Thomas", "Darimont", "tdarimont@example.org");
olli = new User("Oliver", "Gierke", "ogierke@example.org");
ollie = new User("Oliver", "Gierke", "ogierke@example.org");
role = new Role("Developer");
em.persist(role);
tom.getRoles().add(role);
tom = repository.save(tom);
olli = repository.save(olli);
tom.getColleagues().add(olli);
ollie = repository.save(ollie);
tom.getColleagues().add(ollie);
}
/**
@@ -95,7 +98,7 @@ public class EntityGraphRepositoryMethodsIntegrationTests {
assertThat("colleages should be fetched with 'user.detail' fetchgraph",
Persistence.getPersistenceUtil().isLoaded(user.getColleagues()), is(true));
}
/**
* @see DATAJPA-696
*/
@@ -110,7 +113,7 @@ public class EntityGraphRepositoryMethodsIntegrationTests {
assertThat("colleages should be fetched with 'user.detail' fetchgraph",
Persistence.getPersistenceUtil().isLoaded(user.getColleagues()), is(true));
}
/**
* @see DATAJPA-696
*/

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2015 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.jpa.repository.query;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
import javax.persistence.EntityGraph;
import javax.persistence.Subgraph;
import org.junit.Test;
import org.springframework.data.jpa.repository.EntityGraph.EntityGraphType;
/**
* Unit tests for {@link Jpa21Utils}.
*
* @author Thomas Darimont
* @author Oliver Gierke
*/
public class Jpa21UtilsUnitTests {
/**
* @see DATAJPA-696
*/
@Test
public void shouldBuildCorrectSubgraphForJpaEntityGraph() throws Exception {
EntityGraph<?> entityGraph = mock(EntityGraph.class);
Subgraph<?> subgraph = mock(Subgraph.class);
doReturn(subgraph).when(entityGraph).addSubgraph(anyString());
JpaEntityGraph jpaEntityGraph = new JpaEntityGraph("foo", EntityGraphType.FETCH,
new String[] { "foo", "gugu.gaga" });
Jpa21Utils.configureFetchGraphFrom(jpaEntityGraph, entityGraph);
verify(entityGraph, times(1)).addAttributeNodes("foo");
verify(entityGraph, times(1)).addSubgraph("gugu");
verify(subgraph, times(1)).addAttributeNodes("gaga");
}
}

View File

@@ -21,6 +21,7 @@ import org.springframework.data.jpa.domain.sample.User;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.EntityGraph.EntityGraphType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;
/**
* Custom repository interface that customizes the fetching behavior of querys of well known repository interface
@@ -28,7 +29,7 @@ import org.springframework.data.jpa.repository.JpaRepository;
*
* @author Thomas Darimont
*/
public interface RepositoryMethodsWithEntityGraphConfigJpaRepository extends JpaRepository<User, Integer> {
public interface RepositoryMethodsWithEntityGraphConfigRepository extends CrudRepository<User, Integer> {
/**
* Should find all users.