DATAJPA-12 - Added Sort implementations for JPA meta-model API and Querydsl.
Introduced JpaSort for sorting by JPA meta-model attribute paths. Introduced JpaMetaModelPathBuilder that can be used to ease the construction of Jpa meta-model attribute paths by the provided static factory method. Added new testing scenario (MailMessage and MailSender) to avoid to mess up the existing sample classes. Enabled static JPA meta-model generation in pom.xml. Enhanced Querydsl to generate appropriate left joins when sorting by nested (singular) association properties. Converted XML configuration for QueryDslRepositorySupportIntegrationTests into JavaConfig. Original pull request: #54.
This commit is contained in:
committed by
Oliver Gierke
parent
e51add8c76
commit
692b2382bf
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright 2013 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.domain;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.jpa.support.JpaMetaModelPathBuilder.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Path;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportResource;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.jpa.domain.sample.MailMessage_;
|
||||
import org.springframework.data.jpa.domain.sample.MailSender_;
|
||||
import org.springframework.data.jpa.domain.sample.User;
|
||||
import org.springframework.data.jpa.domain.sample.User_;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* Unit test for {@link JpaSort}.
|
||||
*
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class JpaSortTests {
|
||||
|
||||
@Configuration
|
||||
@ImportResource("classpath:infrastructure.xml")
|
||||
static class Config {}
|
||||
|
||||
@PersistenceContext EntityManager em;
|
||||
|
||||
private static final MailMessage_ jmail = null;
|
||||
private static final MailSender_ jsender = null;
|
||||
|
||||
/**
|
||||
* @see DATAJPA-12
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void shouldThrowIfNoOrderSpecifiersAreGiven() {
|
||||
new JpaSort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-12
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void shouldThrowIfNullIsGiven() {
|
||||
new JpaSort((List<Path<?>>) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-12
|
||||
*/
|
||||
@Test
|
||||
public void sortBySinglePropertyWithDefaultSortDirection() {
|
||||
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<User> q = cb.createQuery(User.class);
|
||||
Root<User> c = q.from(User.class);
|
||||
|
||||
JpaSort sort = new JpaSort(c.get("firstname"));
|
||||
|
||||
assertThat(sort, hasItems(new Sort.Order("firstname")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-12
|
||||
*/
|
||||
@Test
|
||||
public void sortByMultiplePropertiesWithDefaultSortDirection() {
|
||||
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<User> q = cb.createQuery(User.class);
|
||||
Root<User> c = q.from(User.class);
|
||||
|
||||
JpaSort sort = new JpaSort(c.get("firstname"), c.get("lastname"));
|
||||
assertThat(sort, hasItems(new Sort.Order("firstname"), new Sort.Order("lastname")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-12
|
||||
*/
|
||||
@Test
|
||||
public void sortByMultiplePropertiesWithDescSortDirection() {
|
||||
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<User> q = cb.createQuery(User.class);
|
||||
Root<User> c = q.from(User.class);
|
||||
|
||||
JpaSort sort = new JpaSort(Direction.DESC, c.get("firstname"), c.get("lastname"));
|
||||
|
||||
assertThat(sort, hasItems(new Sort.Order(Direction.DESC, "firstname"), new Sort.Order(Direction.DESC, "lastname")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-12
|
||||
*/
|
||||
@Test
|
||||
public void combiningSortByMultipleProperties() {
|
||||
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<User> q = cb.createQuery(User.class);
|
||||
Root<User> c = q.from(User.class);
|
||||
|
||||
Sort sort = new JpaSort(c.get("firstname")).and(new JpaSort(c.get("lastname")));
|
||||
|
||||
assertThat(sort, hasItems(new Sort.Order("firstname"), new Sort.Order("lastname")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-12
|
||||
*/
|
||||
@Test
|
||||
public void combiningSortByMultiplePropertiesWithDifferentSort() {
|
||||
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<User> q = cb.createQuery(User.class);
|
||||
Root<User> c = q.from(User.class);
|
||||
|
||||
Sort sort = new JpaSort(c.get("firstname")).and(new JpaSort(Direction.DESC, c.get("lastname")));
|
||||
|
||||
assertThat(sort, hasItems(new Sort.Order("firstname"), new Sort.Order(Direction.DESC, "lastname")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-12
|
||||
*/
|
||||
@Test
|
||||
public void combiningSortByNestedEmbeddedProperty() {
|
||||
|
||||
CriteriaBuilder cb = em.getCriteriaBuilder();
|
||||
CriteriaQuery<User> q = cb.createQuery(User.class);
|
||||
Root<User> c = q.from(User.class);
|
||||
|
||||
Sort sort = new JpaSort(c.get("address").get("streetName"));
|
||||
|
||||
assertThat(sort, hasItems(new Sort.Order("address.streetName")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-12
|
||||
*/
|
||||
@Test
|
||||
public void buildJpaSortFromJpaMetaModelSingleAttribute() {
|
||||
|
||||
Sort sort = new JpaSort(Direction.ASC, path(User_.firstname).build(em));
|
||||
|
||||
assertThat(sort, hasItems(new Sort.Order("firstname")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-12
|
||||
*/
|
||||
@Test
|
||||
public void buildJpaSortFromJpaMetaModelNestedAttribute() {
|
||||
|
||||
Sort sort = new JpaSort(Direction.ASC, path(MailMessage_.mailSender).get(MailSender_.name).build(em));
|
||||
|
||||
assertThat(sort, hasItems(new Sort.Order("mailSender.name")));
|
||||
}
|
||||
}
|
||||
59
src/test/java/org/springframework/data/jpa/domain/sample/MailMessage.java
Executable file
59
src/test/java/org/springframework/data/jpa/domain/sample/MailMessage.java
Executable file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2013 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.domain.sample;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToOne;
|
||||
|
||||
/**
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Entity
|
||||
public class MailMessage {
|
||||
|
||||
@Id @GeneratedValue private Long id;
|
||||
|
||||
@OneToOne(cascade = CascadeType.ALL) private MailSender mailSender;
|
||||
|
||||
private String content;
|
||||
|
||||
public MailSender getMailSender() {
|
||||
return mailSender;
|
||||
}
|
||||
|
||||
public void setMailSender(MailSender sender) {
|
||||
this.mailSender = sender;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2013 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.domain.sample;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Entity
|
||||
public class MailSender {
|
||||
|
||||
@Id @GeneratedValue private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
public MailSender() {}
|
||||
|
||||
public MailSender(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
MailSender other = (MailSender) obj;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -64,10 +64,7 @@ public class User {
|
||||
* Creates a new empty instance of {@code User}.
|
||||
*/
|
||||
public User() {
|
||||
|
||||
this.roles = new HashSet<Role>();
|
||||
this.colleagues = new HashSet<User>();
|
||||
this.createdAt = new Date();
|
||||
this(null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,13 +74,15 @@ public class User {
|
||||
* @param lastname
|
||||
* @param emailAddress
|
||||
*/
|
||||
public User(final String firstname, final String lastname, final String emailAddress) {
|
||||
public User(String firstname, String lastname, String emailAddress) {
|
||||
|
||||
this();
|
||||
this.firstname = firstname;
|
||||
this.lastname = lastname;
|
||||
this.emailAddress = emailAddress;
|
||||
this.active = true;
|
||||
this.roles = new HashSet<Role>();
|
||||
this.colleagues = new HashSet<User>();
|
||||
this.createdAt = new Date();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,7 +35,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
*/
|
||||
@Configuration
|
||||
@EnableTransactionManagement
|
||||
class InfrastructureConfig {
|
||||
public class InfrastructureConfig {
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2013 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.sample;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.domain.sample.MailMessage;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
|
||||
|
||||
import com.mysema.query.types.OrderSpecifier;
|
||||
import com.mysema.query.types.Predicate;
|
||||
|
||||
/**
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
public interface MailMessageRepository extends JpaRepository<MailMessage, Long>, QueryDslPredicateExecutor<MailMessage> {
|
||||
|
||||
List<MailMessage> findAll(Predicate predicate, OrderSpecifier<?>... orders);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2013 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.support;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.jpa.support.JpaMetaModelPathBuilder.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.jpa.domain.JpaSort;
|
||||
import org.springframework.data.jpa.domain.sample.MailMessage;
|
||||
import org.springframework.data.jpa.domain.sample.MailMessage_;
|
||||
import org.springframework.data.jpa.domain.sample.MailSender;
|
||||
import org.springframework.data.jpa.domain.sample.MailSender_;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.data.jpa.repository.config.InfrastructureConfig;
|
||||
import org.springframework.data.jpa.repository.sample.MailMessageRepository;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Transactional
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class JpaMetaModelRepositoryUnitTests {
|
||||
|
||||
@Configuration
|
||||
@Import(InfrastructureConfig.class)
|
||||
@EnableJpaRepositories(basePackageClasses = MailMessageRepository.class)
|
||||
static class Config {}
|
||||
|
||||
private static final MailMessage_ jmail = null;
|
||||
private static final MailSender_ jsender = null;
|
||||
|
||||
@PersistenceContext EntityManager em;
|
||||
|
||||
@Autowired MailMessageRepository mailMessageRepository;
|
||||
|
||||
/**
|
||||
* @see DATAJPA-12
|
||||
*/
|
||||
@Test
|
||||
public void shouldSortMailWithPageRequestAndJpaSortCriteriaNullsFirst() {
|
||||
|
||||
MailMessage message1 = new MailMessage();
|
||||
message1.setContent("abc");
|
||||
MailSender sender1 = new MailSender("foo");
|
||||
message1.setMailSender(sender1);
|
||||
|
||||
MailMessage message2 = new MailMessage();
|
||||
message2.setContent("abc");
|
||||
|
||||
mailMessageRepository.save(message1);
|
||||
mailMessageRepository.save(message2);
|
||||
|
||||
Page<MailMessage> results = mailMessageRepository.findAll(new PageRequest(0, 20, //
|
||||
new JpaSort(Direction.ASC, path(jmail.mailSender).get(jsender.name).build(em))));
|
||||
List<MailMessage> messages = results.getContent();
|
||||
|
||||
assertThat(messages, hasSize(2));
|
||||
assertThat(messages.get(0).getMailSender(), is(nullValue()));
|
||||
assertThat(messages.get(1).getMailSender(), is(sender1));
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,8 @@ import org.springframework.data.domain.Sort.Order;
|
||||
import org.springframework.data.jpa.domain.sample.Address;
|
||||
import org.springframework.data.jpa.domain.sample.QUser;
|
||||
import org.springframework.data.jpa.domain.sample.User;
|
||||
import org.springframework.data.querydsl.QPageRequest;
|
||||
import org.springframework.data.querydsl.QSort;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -215,4 +217,60 @@ public class QueryDslJpaRepositoryTests {
|
||||
assertThat(page.getContent(), hasItems(dave, carter, oliver));
|
||||
assertThat(page.getContent().get(2), is(oliver));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-12
|
||||
*/
|
||||
@Test
|
||||
public void findBySpecificationWithSortByQueryDslOrderSpecifierWithQPageRequestAndQSort() {
|
||||
|
||||
QUser user = QUser.user;
|
||||
|
||||
Page<User> page = repository.findAll(user.firstname.isNotNull(),
|
||||
new QPageRequest(0, 10, new QSort(user.firstname.asc())));
|
||||
|
||||
assertThat(page.getContent(), hasSize(3));
|
||||
assertThat(page.getContent(), hasItems(carter, dave, oliver));
|
||||
assertThat(page.getContent().get(0), is(carter));
|
||||
assertThat(page.getContent().get(1), is(dave));
|
||||
assertThat(page.getContent().get(2), is(oliver));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-12
|
||||
*/
|
||||
@Test
|
||||
public void findBySpecificationWithSortByQueryDslOrderSpecifierWithQPageRequest() {
|
||||
|
||||
QUser user = QUser.user;
|
||||
|
||||
Page<User> page = repository.findAll(user.firstname.isNotNull(), new QPageRequest(0, 10, user.firstname.asc()));
|
||||
|
||||
assertThat(page.getContent(), hasSize(3));
|
||||
assertThat(page.getContent(), hasItems(carter, dave, oliver));
|
||||
assertThat(page.getContent().get(0), is(carter));
|
||||
assertThat(page.getContent().get(1), is(dave));
|
||||
assertThat(page.getContent().get(2), is(oliver));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-12
|
||||
*/
|
||||
@Test
|
||||
public void findBySpecificationWithSortByQueryDslOrderSpecifierForAssociationShouldGenerateLeftJoinWithQPageRequest() {
|
||||
|
||||
oliver.setManager(dave);
|
||||
dave.setManager(carter);
|
||||
|
||||
QUser user = QUser.user;
|
||||
|
||||
Page<User> page = repository.findAll(user.firstname.isNotNull(),
|
||||
new QPageRequest(0, 10, user.manager.firstname.asc()));
|
||||
|
||||
assertThat(page.getContent(), hasSize(3));
|
||||
assertThat(page.getContent(), hasItems(carter, dave, oliver));
|
||||
assertThat(page.getContent().get(0), is(carter));
|
||||
assertThat(page.getContent().get(1), is(dave));
|
||||
assertThat(page.getContent().get(2), is(oliver));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* Copyright 2011-2013 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,96 @@
|
||||
*/
|
||||
package org.springframework.data.jpa.repository.support;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.jpa.domain.sample.MailMessage;
|
||||
import org.springframework.data.jpa.domain.sample.MailSender;
|
||||
import org.springframework.data.jpa.domain.sample.QMailMessage;
|
||||
import org.springframework.data.jpa.domain.sample.QMailSender;
|
||||
import org.springframework.data.jpa.domain.sample.User;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.data.jpa.repository.config.InfrastructureConfig;
|
||||
import org.springframework.data.jpa.repository.sample.MailMessageRepository;
|
||||
import org.springframework.data.jpa.repository.support.QueryDslRepositorySupportTests.UserRepository;
|
||||
import org.springframework.data.jpa.repository.support.QueryDslRepositorySupportTests.UserRepositoryImpl;
|
||||
import org.springframework.data.querydsl.QPageRequest;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* Integration test for the setup of beans extending {@link QueryDslRepositorySupport}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@Transactional
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration("classpath:querydsl.xml")
|
||||
public class QueryDslRepositorySupportIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
UserRepository repository;
|
||||
@Configuration
|
||||
@EnableJpaRepositories(basePackageClasses = MailMessageRepository.class, includeFilters = @Filter(
|
||||
type = FilterType.ASSIGNABLE_TYPE, value = { MailMessageRepository.class }))
|
||||
@EnableTransactionManagement
|
||||
static class Config extends InfrastructureConfig {
|
||||
@Bean
|
||||
public UserRepositoryImpl userRepositoryImpl() {
|
||||
|
||||
@Autowired
|
||||
ReconfiguringUserRepositoryImpl reconfiguredRepo;
|
||||
return new UserRepositoryImpl() {
|
||||
@Override
|
||||
@PersistenceContext(unitName = "querydsl")
|
||||
public void setEntityManager(EntityManager entityManager) {
|
||||
super.setEntityManager(entityManager);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@PersistenceContext(unitName = "querydsl")
|
||||
EntityManager em;
|
||||
@Bean
|
||||
public ReconfiguringUserRepositoryImpl reconfiguringUserRepositoryImpl() {
|
||||
return new ReconfiguringUserRepositoryImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EntityManagerContainer entityManagerContainer() {
|
||||
return new EntityManagerContainer();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
|
||||
|
||||
LocalContainerEntityManagerFactoryBean emf = super.entityManagerFactory();
|
||||
emf.setPersistenceUnitName("querydsl");
|
||||
return emf;
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired UserRepository repository;
|
||||
|
||||
@Autowired ReconfiguringUserRepositoryImpl reconfiguredRepo;
|
||||
|
||||
@Autowired MailMessageRepository mailMessageRepository;
|
||||
|
||||
@PersistenceContext(unitName = "querydsl") EntityManager em;
|
||||
|
||||
static final QMailMessage qmail = QMailMessage.mailMessage;
|
||||
static final QMailSender qsender = QMailSender.mailSender;
|
||||
|
||||
@Test
|
||||
public void createsRepoCorrectly() {
|
||||
@@ -62,6 +121,56 @@ public class QueryDslRepositorySupportIntegrationTests {
|
||||
assertThat(reconfiguredRepo.getEntityManager().getEntityManagerFactory(), is(em.getEntityManagerFactory()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-12
|
||||
*/
|
||||
@Test
|
||||
public void shouldSortMailWithQueryDslRepositoryAndQPageRequestDslSortCriteriaNullsFirst() {
|
||||
|
||||
MailMessage message1 = new MailMessage();
|
||||
message1.setContent("abc");
|
||||
MailSender sender1 = new MailSender("foo");
|
||||
message1.setMailSender(sender1);
|
||||
|
||||
MailMessage message2 = new MailMessage();
|
||||
message2.setContent("abc");
|
||||
|
||||
mailMessageRepository.save(message1);
|
||||
mailMessageRepository.save(message2);
|
||||
|
||||
Page<MailMessage> results = mailMessageRepository.findAll(qmail.content.eq("abc"), new QPageRequest(0, 20,
|
||||
qsender.name.asc()));
|
||||
List<MailMessage> messages = results.getContent();
|
||||
|
||||
assertThat(messages, hasSize(2));
|
||||
assertThat(messages.get(0).getMailSender(), is(nullValue()));
|
||||
assertThat(messages.get(1).getMailSender(), is(sender1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-12
|
||||
*/
|
||||
@Test
|
||||
public void shouldSortMailWithQueryDslRepositoryAndDslSortCriteriaNullsFirst() {
|
||||
|
||||
MailMessage message1 = new MailMessage();
|
||||
message1.setContent("abc");
|
||||
MailSender sender1 = new MailSender("foo");
|
||||
message1.setMailSender(sender1);
|
||||
|
||||
MailMessage message2 = new MailMessage();
|
||||
message2.setContent("abc");
|
||||
|
||||
mailMessageRepository.save(message1);
|
||||
mailMessageRepository.save(message2);
|
||||
|
||||
List<MailMessage> messages = mailMessageRepository.findAll(qmail.content.eq("abc"), qmail.mailSender.name.asc());
|
||||
|
||||
assertThat(messages, hasSize(2));
|
||||
assertThat(messages.get(0).getMailSender(), is(nullValue()));
|
||||
assertThat(messages.get(1).getMailSender(), is(sender1));
|
||||
}
|
||||
|
||||
static class ReconfiguringUserRepositoryImpl extends QueryDslRepositorySupport {
|
||||
|
||||
public ReconfiguringUserRepositoryImpl() {
|
||||
@@ -77,7 +186,6 @@ public class QueryDslRepositorySupportIntegrationTests {
|
||||
|
||||
static class EntityManagerContainer {
|
||||
|
||||
@PersistenceContext(unitName = "querydsl")
|
||||
EntityManager em;
|
||||
@PersistenceContext(unitName = "querydsl") EntityManager em;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* Copyright 2011-2013 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.
|
||||
@@ -36,14 +36,14 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
* Integration test for {@link QueryDslRepositorySupport}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration({ "classpath:infrastructure.xml" })
|
||||
@Transactional
|
||||
public class QueryDslRepositorySupportTests {
|
||||
|
||||
@PersistenceContext
|
||||
EntityManager em;
|
||||
@PersistenceContext EntityManager em;
|
||||
|
||||
UserRepository repository;
|
||||
User dave, carter;
|
||||
|
||||
Reference in New Issue
Block a user